[英]Mocking function object with jest
我目前有一个 object 用于与我的 API api.js
:
export var Auth = (function () {
var Login = async function(username, password) {
//Async login code for interacting with the API
};
return {
Login: Login
}
});
这个 object 被导入到另一个文件login.js
中:
import * as API from './api';
export var LoginRequestHandler = function() {
//processess user input, then calls:
try {
await API.Auth().Login(username, password);
} catch(e) {
throw new Error(e);
}
这是我的笑话测试:
import * as API from '../api';
import * as User from '../user';
jest.mock('../api');
const spy = jest.spyOn(API.Auth(), 'Login');
User.LoginRequestHandler().then(() => {
expect(spy).toHaveBeenLastCalledWith('theUsername', 'thePassword');
}).catch(error => console.log(error));
这是我的模拟文件__mock__/api.js
:
export var Auth = (function () {
var Login = async function(username, password) {
return Promise.resolve(true);
};
return {
Login: Login
}
});
我通过theUsername
中的LoginRequestHandler
document.getElementId()
检索用户名和thePassword
,并为上面的测试创建自己的 DOM。
在LoginRequestHandler
中添加console.log(username)
表明它正在被调用并且能够获取正确的值。 此外,在API.Auth().Login
中添加一个console.log(username)
也表明它也获得了正确的值。 但是,当我查看测试日志时,我看到:模拟 function Number of calls: 0
并且测试结果出现错误。
我假设我试图监视错误的 function,无论如何我可以解决这个问题吗?
每次调用API.Auth()
时,它都会返回一个新的 object ,它有一个Login
方法。 因此,在LoginRequestHandler
function 中创建并由jest.spyOn(API.Auth(), 'Login')
语句在您的测试用例中创建的 object 是不同的。 间谍只添加到后一个。 LoginRequestHandler
function 中的Login
方法未被窥探。
所以,在这里我将使用jest.mock()
来模拟api.js
模块,而不将模拟的 object 放到__mocks__
目录中。 例如
api.js
:
export var Auth = function () {
var Login = async function (username, password) {};
return {
Login: Login,
};
};
user.js
:
import * as API from './api';
export var LoginRequestHandler = async function () {
const username = 'theUsername';
const password = 'thePassword';
try {
await API.Auth().Login(username, password);
} catch (e) {
throw new Error(e);
}
};
user.test.js
:
import * as API from './api';
import * as User from './user';
jest.mock('./api', () => {
const auth = { Login: jest.fn() };
return {
Auth: jest.fn(() => auth),
};
});
describe('61643983', () => {
afterEach(() => {
jest.clearAllMocks();
});
it('should login', () => {
expect.assertions(2);
return User.LoginRequestHandler().then(() => {
expect(API.Auth).toBeCalledTimes(1);
expect(API.Auth().Login).toHaveBeenLastCalledWith('theUsername', 'thePassword');
});
});
it('should throw error', () => {
expect.assertions(4);
const mError = new Error('user not found');
API.Auth().Login.mockRejectedValueOnce(mError);
return User.LoginRequestHandler().catch((e) => {
expect(API.Auth).toBeCalled();
expect(API.Auth().Login).toHaveBeenLastCalledWith('theUsername', 'thePassword');
expect(e).toBeInstanceOf(Error);
expect(e.message).toMatch(/user not found/);
});
});
});
覆盖率 100% 的单元测试结果:
PASS stackoverflow/61643983/user.test.js (11.507s)
61643983
✓ should login (5ms)
✓ should throw error (3ms)
----------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
----------|---------|----------|---------|---------|-------------------
All files | 100 | 100 | 100 | 100 |
user.js | 100 | 100 | 100 | 100 |
----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests: 2 passed, 2 total
Snapshots: 0 total
Time: 13.023s
源代码: https://github.com/mrdulin/react-apollo-graphql-starter-kit/tree/master/stackoverflow/61643983
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.