2011-12-05 10 views
34

मैं फ़ेलिक्स node-mysql क्लाइंट के साथ Node.js का उपयोग कर रहा हूं। मैं एक ओआरएम का उपयोग नहीं कर रहा हूँ।आप Node.js में MySQL (ओआरएम के बिना) कैसे नकल करते हैं?

मैं शपथ के साथ परीक्षण कर रहा हूं और संभवतः साइनऑन का उपयोग करके अपने डेटाबेस को नकल करने में सक्षम होना चाहता हूं। चूंकि मेरे पास वास्तव में एक डीएएल प्रति नहीं है (node-mysql से अलग), मुझे सच में यकीन नहीं है कि इस बारे में कैसे जाना है। मेरे मॉडल ज्यादातर गेटर्स के साथ अधिक सरल सीआरयूडी हैं।

इसे पूरा करने के तरीके पर कोई विचार?

+0

क्या आप मुझे और विवरण दे सकते हैं? उदाहरण के लिए कुछ कोड पेस्ट करें और शायद आप जो प्राप्त करना चाहते हैं उसका एक स्यूडोकोड दिखाएं? मैं मदद करना चाहूंगा। – alessioalex

+0

@alessioalex मैं ईमानदारी से वास्तव में यह भी नहीं जानता कि कहां से शुरू करना है। वास्तव में आदर्श रूप में मैं किसी और के मॉडल वर्ग और उनके संबंधित मैक्स/परीक्षण देखना चाहता हूं। –

उत्तर

22

सिनोन के साथ, आप एक पूरे मॉड्यूल के चारों ओर एक नकली या ठूंठ रख सकते हैं:

यहाँ एक छोटा सा उदाहरण है। उदाहरण के लिए, मान लीजिए mysql मॉड्यूल एक समारोह query है:

var mock; 

mock = sinon.mock(require('mysql')) 
mock.expects('query').with(queryString, queryParams).yields(null, rows); 

queryString, queryParams इनपुट जैसा कि आप उम्मीद कर रहे हैं। rows वह आउटपुट है जिसे आप उम्मीद करते हैं।

जब आपकी कक्षा के परीक्षण के तहत अब mysql की आवश्यकता होती है और query विधि को कॉल करती है, तो इसे साइनऑन द्वारा अवरुद्ध और सत्यापित किया जाएगा।

अपने परीक्षण उम्मीद अनुभाग में आप होना चाहिए:

mock.verify() 

और अपने टियरडाउन में आप सामान्य कार्यक्षमता को वापस mysql बहाल करना चाहिए: का उपयोग कर

mock.restore() 
+1

.with() को .withArgs() के पक्ष में बहिष्कृत किया गया प्रतीत होता है। मैं साइनऑन के साथ परीक्षण कर रहा हूं 1.7.2 – AndreiM

+1

यदि आपने एक पूर्ण उदाहरण दिया है तो अपरिवर्तित होगा। –

4

मैं node.js से पूरी तरह से परिचित नहीं हूं, लेकिन पारंपरिक प्रोग्रामिंग भावना में, इस तरह के परीक्षण को प्राप्त करने के लिए, आपको डेटा एक्सेस विधि से दूर करने की आवश्यकता होगी। आप की तरह एक दाल वर्ग नहीं बना सका:

DataContainer.prototype.getAllBooks = function() { 
    // Here is where you'd return your mock data in whatever format is expected. 
    return []; 
} 

जब परीक्षण कोड कहा जाता है, getAllBooks हो जाएगा: एक परीक्षण के संदर्भ में अब

var DataContainer = function() { 
} 

DataContainer.prototype.getAllBooks = function() { 
    // call mysql api select methods and return results... 
} 

, जैसे आरंभीकरण के दौरान अपने getAllBooks वर्ग पैच एक संस्करण के साथ प्रतिस्थापित किया गया है जो वास्तव में mysql को कॉल करने के बजाय नकली डेटा देता है। दोबारा, यह एक मोटा अवलोकन है क्योंकि मैं node.js

7

से पूरी तरह से परिचित नहीं हूं, यह आपके डेटाबेस को अपनी कक्षा में अमूर्त करने के लिए एक अच्छा विचार हो सकता है जो mysql का उपयोग करता है। फिर आप उस वर्ग के उदाहरण को अपने मॉडल के कन्स्ट्रक्टर को पास करने के बजाय इसे लोड करने के बजाय पास कर सकते हैं()।

इस सेट के साथ आप अपनी यूनिट परीक्षण फ़ाइलों के अंदर अपने मॉडल में एक नकली डीबी उदाहरण पास कर सकते हैं।

// db.js 
var Db = function() { 
    this.driver = require('mysql'); 
}; 
Db.prototype.query = function(sql, callback) { 
    this.driver... callback (err, results); 
} 
module.exports = Db; 

// someModel.js 
var SomeModel = function (params) { 
    this.db = params.db 
} 
SomeModel.prototype.getSomeTable (params) { 
    var sql = .... 
    this.db.query (sql, function (err, res) {...} 
} 
module.exports = SomeModel; 

// in app.js 
var db = new (require('./db.js'))(); 
var someModel = new SomeModel ({db:db}); 
var otherModel = new OtherModel ({db:db}) 

// in app.test.js 
var db = { 
    query: function (sql, callback) { ... callback ({...}) } 
} 
var someModel = new SomeModel ({db:db}); 
3

आप बाहर नकली कर सकते हैं बाहरी निर्भरता horaa

और मुझे यह भी विश्वास है कि फ़ेलिक्स का नोड sandboxed-module कुछ ऐसा ही कर सकता है।

तो kgilpin के ही संदर्भ का उपयोग करते हुए, Horaa में यह कुछ ऐसा दिखाई देगा:

var mock = horaa('mysql'); 
mock.hijack('query', function(queryString, queryParam) { 
    // do your fake db query (e.g., return fake expected data) 
}); 

//SUT calls and asserts 

mock.restore('query'); 
+0

sinon.js इन दिनों defacto प्रतीत होता है – dule

1

मैं @ kgilpin के जवाब के साथ शुरू समाप्त हो गया और कुछ इस तरह एक एडब्ल्यूएस लैम्ब्डा में Mysql का परीक्षण करने के साथ समाप्त हो गया:

const sinon = require('sinon'); 
const LambdaTester = require('lambda-tester'); 
const myLambdaHandler = require('../../lambdas/myLambda').handler; 
const mockMysql = sinon.mock(require('mysql')); 
const chai = require('chai'); 
const expect = chai.expect; 

describe('Database Write Requests', function() { 

beforeEach(() => { 
    mockMysql.expects('createConnection').returns({ 
    connect:() => { 
     console.log('Succesfully connected'); 
    }, 
    query: (query, vars, callback) => { 
     callback(null, succesfulDbInsert); 
    }, 
    end:() => { 
     console.log('Connection ended'); 
    } 
    }); 

}); 
after(() => { 
    mockMysql.restore(); 
}); 

describe('A call to write to the Database with correct schema', function() { 

    it('results in a write success', function() { 

    return LambdaTester(myLambdaHandler) 
     .event(anObject) 
     .expectResult((result) => { 
     expect(result).to.equal(succesfulDbInsert); 
     }); 
    }); 
}); 


describe('database errors', function() { 

    before(() => { 
    mockMysql.expects('createConnection').returns({ 
     connect:() => { 
     console.log('Succesfully connected'); 
     }, 
     query: (query, vars, callback) => { 
     callback('Database error!', null); 
     }, 
     end:() => { 
     console.log('Connection ended'); 
     } 
    }); 
    }); 

    after(() => { 
    mockMysql.restore(); 
    }); 

    it('results in a callback error response', function() { 


    return LambdaTester(myLambdaHandler) 
     .event(anObject) 
     .expectError((err) => { 
     expect(err.message).to.equal('Something went wrong'); 
     }); 
    }); 
}); 
}); 

मुझे कोई वास्तविक डेटाबेस कनेक्शन नहीं चाहिए इसलिए मैंने मैन्युअल रूप से सभी mysql प्रतिक्रियाओं का मज़ाक उड़ाया।
.returns पर एक और फ़ंक्शन जोड़ा गया है, तो आप createConnection से किसी भी विधि का नकल कर सकते हैं।

संबंधित मुद्दे