我正在尝试使用 mocha , chai , chai-spies 和快速应用 >再布线即可。
特别是,我想要做的是模拟模块中存在的函数并使用chai间谍。
我有一个名为db.js
的模块,它导出saveUser()
方法
db.js
module.exports.saveUser = (user) => {
// saves user to database
};
app.js
模块
app.js
const db = require('./db');
module.exports.handleSignUp = (email, password) => {
// create user object
let user = {
email: email,
password: password
};
// save user to database
db.saveUser(user); // <-- I want want to mock this in my test !!
};
最后在我的测试文件app.test.js
中,我有以下
app.test.js
const chai = require('chai')
, spies = require('chai-spies')
, rewire = require('rewire');
chai.use(spies);
const expect = chai.expect;
// Mock the db.saveUser method within app.js
let app = rewire('./app');
let dbMock = {
saveUser: chai.spy()
};
app.__set__('db', dbMock);
// Perform the test
it('should call saveUser', () => {
let email = 'someone@example.com'
, password = '123456';
// run the method we want to test
app.handleSignUp(email, password);
// assert that the spy is called
expect(dbMock.saveUser).to.be.spy; // <--- this test passes
expect(dbMock.saveUser).to.have.been.called(); // <--- this test fails
});
我的问题是我确保app.handleSignUp调用间谍的测试失败如下
AssertionError: expected { Spy } to have been called at Context.it (spies/app.test.js:25:40)
我觉得我做错了什么但我现在卡住了。感谢任何帮助,谢谢
答案 0 :(得分:4)
最后,我弄清楚问题是什么。来自rewire github页面:
限制
使用const它不可能重新连接const(参见#79)。这个可以 可能有一天会被代理人解决,但需要进一步研究。
因此,在const db = require('./db');
中将let db = require('./db');
更改为app.js
会使所有测试通过。
但是,由于将所有const
声明更改为let
以便使用间谍测试应用程序是一件麻烦事,因此以下方法似乎更好:
我们可以要求db
中的app.js
模块作为const
,而不是创建间谍并覆盖const变量:
let dbMock = {
saveUser: chai.spy()
};
app.__set__('db', dbMock);
我们可以使用rewire
getter 方法导入db
文件中的app.test.js
模块,然后模拟{{1使用我们的间谍的方法(即 mutate saveUser()
变量的属性之一;因为JS中的对象是通过引用传递的,所以获取并改变{{1} app.test.js模块中的对象也会改变app.js模块中的同一个对象)
const
最后,我们可以预期变异的db
(即我们的间谍)将被称为
const db = app.__get__('db');
db.saveUser = chai.spy()
总而言之,db.saveUser
和expect(db.saveUser).to.have.been.called();
都不会更改,但测试文件现在应如下所示:
db.js