tl;博士
我正在尝试使用 mocha、chai、chai-spies 和 测试 express 应用>重新布线。
特别是,我想做的是模拟模块中存在的函数并使用 chai spy 。
我的设置
我有一个名为 db.js
的模块,它导出 saveUser()
方法
db.js
module.exports.saveUser = (user) => {
// saves user to database
};
app.js
模块需要 db 模块
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 = '<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="41322e2c242e2f24012439202c312d246f222e2c" rel="noreferrer noopener nofollow">[email protected]</a>'
, 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 调用 spy 的测试失败,如下
AssertionError: expected { Spy } to have been called at Context.it (spies/app.test.js:25:40)
我感觉我做错了什么,但此刻我陷入困境。感谢任何帮助,谢谢
最佳答案
终于明白问题出在哪里了。来自 rewire github 页面:
Limitations
Using const It's not possible to rewire const (see #79). This can probably be solved with proxies someday but requires further research.
因此,在 app 中将
使所有测试通过。const db = require('./db');
更改为 let db = require('./db');
.js
更好的解决方案
但是,由于将所有 const
声明更改为 let
以便使用 spy 测试应用程序非常麻烦,因此以下方法似乎更好:
我们可以像我们一样将 app.js
中的 db
模块作为 const
要求,而不是创建 spy 并覆盖常量变量:
let dbMock = {
saveUser: chai.spy()
};
app.__set__('db', dbMock);
我们可以使用rewire
的getter方法在我们的app.test.js
中导入db
模块> 文件,然后使用我们的 spy 模拟 saveUser()
方法(即const
变量的属性之一变异;因为对象JS 通过引用传递,获取和修改 app.test.js 模块中的 db
对象也会修改 app.js 模块中的同一对象)
const db = app.__get__('db');
db.saveUser = chai.spy()
最后,我们可以预期变异的db.saveUser
(即我们的 spy )将被调用
expect(db.saveUser).to.have.been.called();
总而言之,db.js
和 app.js
都不会更改,但测试文件现在应如下所示:
const chai = require('chai')
, spies = require('chai-spies')
, rewire = require('rewire');
chai.use(spies);
let expect = chai.expect;
// Fetch the app object
let app = rewire('./app');
// Use the getter to read the const db object and mutate its saveUser property
const db = app.__get__('db');
db.saveUser = chai.spy()
// Finally perform the test using the mocked
it('should call saveUser', () => {
let email = '<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="2a5945474f45444f6a4f524b475a464f04494547" rel="noreferrer noopener nofollow">[email protected]</a>'
, password = '123456';
// run the method we want to test
app.handleSignUp(email, password);
expect(db.saveUser).to.have.been.called(); // <--- now passes!!!
});
关于javascript - 如何使用 rewirejs 和 chai-spies 模拟函数来测试它?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43498324/