Ilm*_*ula 3 javascript reactjs jestjs enzyme
我正在尝试为更改密码的 React 模块编写单元测试,但我无法在括号中执行代码。我已经为模块 MyAPI 编写了一个模拟,模拟代码执行得很好,并且使用 console.log("something") 我可以在控制台中看到输出。
但是,我无法让代码在 .done(function (data) 之后运行。这很可能是因为模拟正在用它自己的代码替换那些代码。
我知道一种选择是使用像 Nock 这样的假服务器,但除非必须,否则我不想将其变成集成测试。
我正在尝试测试的代码:
const MyAPI = require('../../my_api.js');
submitChangePasswordFormEvent(event) {
const self = this;
const params = {};
event.preventDefault();
event.stopPropagation();
params.current_password = this.refs.current_password.getValue();
params.passwordFirst = this.refs.passwordFirst.getValue();
params.passwordSecond = this.refs.passwordSecond.getValue();
MyAPI.my_api('/api/change_password/', params)
.done(function (data) {
// This code i would like to run but can't
const elem = <Success>{t(['settings',
'passwords_changed'])}</Success>;
self.setState({ pwerror: null, pwsuccess: elem });
self.refs.current_password.value = '';
self.refs.password1.value = '';
self.refs.password2.value = '';
})
.error(function (errors) {
// This code i would like to run but can't
let msg = '';
$.each(errors.responseJSON, function (k, v) {
msg += v;
});
msg = <Error>{msg}</Error>;
self.setState({ pwerror: msg, pwsuccess: null });
});
}
Run Code Online (Sandbox Code Playgroud)
MyAPI 的模拟文件
var MyAPI = function () {};
MyAPI.prototype.my_api = function(url) {
return $.ajax();
}
module.exports = new MyAPI();
Run Code Online (Sandbox Code Playgroud)
Jest 设置脚本:
const jqueryMock = {
ajax: function (argument) {
return {done: function (data) {
return {error: function (errors) {
return "success";
}}}}
}}
global.$ = jqueryMock;
Run Code Online (Sandbox Code Playgroud)
小智 6
您希望执行该方法.done或.error方法,但不想实际发出请求(顺便说一句。我不知道.error方法.fail)?然后我会执行以下操作:
__mocks__在工作目录顶层的目录中为 jquery 创建一个全局模拟:
//__mocks__/jquery.js:
const jQ = jest.requireActual("jquery");
const ajax = jest.fn(() => {
return jQ.Deferred();
});
export const $ = {
...jQ, // We don't want to mock jQuery completely (we might want to alter $.Deferred status)
ajax,
};
export default $;
Run Code Online (Sandbox Code Playgroud)
通过放入目录jquery.js中__mocks__,当您想要测试的模块中请求时,jQuery 会自动被 jest 模拟(好吧,在这种情况下,它会被部分模拟......)。
通过此设置,您可以只运行代码而无需发出实际请求,但可以正常运行方法.done和.error注册的回调。
如果您不想执行已注册的回调,.done或者 .fail您需要手动模拟它们,而不是返回jQ.Deferred()带有玩笑模拟的纯 JavaScript 对象。
.done在您绝对不希望/.error调用您注册的回调的特定测试用例中:
// By returning "this" we are able to chain in the way $.ajax("/api", params).done().fail()
const jqXHR = {
done: jest.fn().mockImplementation(function () {
return this;
}),
fail: jest.fn().mockImplementation(function () {
return this;
}),
// some more $.Deferred() methods you want to mock
};
// Overwrite the global $.ajax mock implementation from __mocks__/jquery.js with our custom one
$.ajax.mockImplementation(() => jqXHR)
Run Code Online (Sandbox Code Playgroud)
当您想在特定测试用例中再次模拟成功或错误时,请覆盖全局模拟实现:
为了成功:
// success
const dfd = $.Deferred();
$.ajax.mockImplementation(() => {
return dfd.resolve("success"); // this is what your done callback will receive as argument
});
Run Code Online (Sandbox Code Playgroud)
对于错误:
// success
const dfd = $.Deferred();
$.ajax.mockImplementation(() => {
return dfd.reject("error"); // this is what your fail callback will receive as argument
});
Run Code Online (Sandbox Code Playgroud)
.done请注意,断言or被调用/未被调用是没有意义的.fail,因为两者总是被调用,因为它们注册了您放入其中的回调。仅当$.Deferred解决或拒绝时,才会执行特定的已注册回调,然后您可以对其进行测试。
.done为了获得更好的单元测试可测试性,您应该从/中提取匿名函数.error。由于 JavaScript 很奇怪并且不像 python(我更喜欢 python),所以你不能轻易地模拟被测模块内的特定函数。因此,您需要将它们放入专用模块中并完全模拟该模块。然后您可以断言它们在成功或错误情况下被调用。
我花了一段时间才弄清楚如何使用 jquery 正确处理模拟,所以我想在这里分享我的经验。希望这可以帮助...
| 归档时间: |
|
| 查看次数: |
3787 次 |
| 最近记录: |