我正在尝试模拟fs.readFileSync()的响应,以便测试我的代码是否在配置文件中返回了一些数据。显然,我不想测试配置文件的内容。
我正在尝试在(api.js)中测试此代码
var fs = require('fs');
var config = JSON.parse(fs.readFileSync('configure.json', 'utf8'));
var Api = {
api_key: config['api-key'],
heartbeat_id: config['resource-id'],
};
如果我可以模拟fs.readFileSync
返回的内容,那么我可以让它返回一些测试值。我的测试是这样的:
var api = require('./api');
var fs = require('fs');
describe('Api object contains correct details', function(){
it('Has an API key of "test API"', function(){
spyOn(fs, 'readFileSync').andReturn(`{
"api-key": "test API",
"resource-id": "Resource ID"
}`);
expect(api.api_key).toBe("test API");
});
});
测试失败,并在我的实际配置文件中返回值。
在api.js
中,您不导出任何要被其他模块使用的内容,所以当在测试文件中时,您会…
var api = require('./api');
您正在直接执行api.js
文件。这意味着,当您的测试在fs.readFileSync
上创建间谍时,该函数已经被api.js
使用,并且您的值注入没有在测试范围中使用。
实现所需功能的一种方法是在api.js
中创建一个根据需要检索配置的函数,并将该函数封装在module.exports
块中。然后,在测试中,需要api.js
会使测试准备好检索配置,因此,如果在检索之前在fs.readFileSync
上创建一个spy,那么将调用该spy,并且可以断言模拟值。
使用Jasmine 2.4.1,它看起来是这样的:
src/api.js
var fs = require('fs');
module.exports = {
getConfig: function() {
var config = JSON.parse(fs.readFileSync('./src/configure.json', 'utf8'));
var Api = {
api_key: config['api-key'],
heartbeat_id: config['resource-id'],
};
return Api;
}
}
spec/api.spec.js
var api = require('../src/api'); // fs.readFileSync hasn't been used yet
var fs = require('fs');
describe('Api object contains correct details', function(){
it('Has an API key of "test API"', function() {
spyOn(fs, 'readFileSync').and.returnValue(`{ // here it's being mocked
"api-key": "test API",
"resource-id": "Resource ID"
}`);
var config = api.getConfig(); // now we are using the mock
expect(config.api_key).toBe("test API");
});
});