我刚刚将lodash导入从func login(email: String , password: String){
let post_data = NSMutableDictionary()
post_data.setValue(email, forKey: "username")
post_data.setValue(password, forKey: "password")
let urlLis = "https://yourbaseUrl/ios/v1/auth/login"
let parameter = [
"email": email,
"password": password
]
Alamofire.request(urlLis, method: .post, parameters: parameter, encoding: URLEncoding.default, headers: nil)
.validate(statusCode: 200..<300)
.responseJSON { response in
switch response.result {
case .success(let data):
print("isi: \(data)")
self.navigationController?.pushViewController(vcbMasuk, animated: true)
case .failure(let error):
alert.addAction(UIAlertAction(title: "Close", style: .default, handler: { (_: UIAlertAction) in
print("OK")
}))
self.present(alert, animated: true, completion: nil)
print("need text")
print("Request failed with error: \(error)")
}
}
}
更改为import _ from 'lodash';
在我的测试中,我曾经有import debounce from 'lodash/debounce';
,但是现在我对将其更改为什么感到困惑。显然sandbox.stub(_, 'debounce').returnsArg(0);
不起作用。从模块仅导出单个功能时,不确定该怎么办。
答案 0 :(得分:0)
此语法:
import something from 'myModule';
...是ES6语法,它将something
绑定到default
'的'myModule
导出。
如果模块是ES6模块,则可以像下面这样对模块的default
导出进行存根:
import * as myModule from 'myModule';
const sinon = require('sinon');
// ...
const stub = sinon.stub(myModule, 'default');
...但是这仅在'myModule'
是ES6模块时有效。
在这种情况下,'lodash/debounce'
不是ES6模块,它是预先编译的。最后一行是这样的:
module.exports = debounce;
...这表示模块导出是去抖功能。
这意味着要存根'lodash/debounce'
,您必须模拟整个模块。
Sinon不提供模块级模拟,因此您需要使用类似proxyquire
的东西:
const proxyquire = require('proxyquire');
const sinon = require('sinon');
const debounceStub = sinon.stub().returnsArg(0);
const code = proxyquire('[path to your code]', { 'lodash/debounce': debounceStub })
...或者如果您使用的是Jest
,则可以使用类似jest.mock
的内容:
jest.mock('lodash/debounce', () =>
jest.fn((func, ms) => func) // <= mock debounce to simply return the function
);
详细信息
仅在模块为ES6模块的情况下才暂停default
模块导出的原因是因为编译期间发生了什么。
ES6语法被编译到ES6之前的JavaScript中。例如,Babel将其变为:
import something from 'myModule';
...变成这样:
var _myModule = _interopRequireDefault(require("myModule"));
function _interopRequireDefault(obj) {
return obj && obj.__esModule ?
obj : // <= return the result of require("myModule") if it is an ES6 module...
{ default: obj }; // <= otherwise set it to the default property of a wrapper object
}
...因此,如果'myModule'
是ES6模块,它将直接返回...但是,如果不是,则互操作返回一个包装对象。
由于每个import
获得一个不同的包装对象,因此更改其中一个的default
属性不会影响其他任何对象的default
属性。
答案 1 :(得分:0)
您可以使自己成为包装文件,最终将为您导出相同的lodash/debounce
实例,但是这次您可以对它进行存根,例如:
myutils / lodash / debounce.js
import lodashDebounce from 'lodash/debounce';
const exports = {
debounce: lodashDebounce,
};
export const debounce = () => exports.debounce();
export default exports;
现在,在您的实际代码中,debounce
不是从原始位置而是从该包装文件中导入:
之前:
import debounce from 'lodash/debounce' // this is how we usually do
之后:
import { debounce } from 'myutils/lodash/debounce' // if we want to stub it
// all other code-lines remain the same
const method = () => {
debounce(callback, 150));
...
}
现在执行 test.js 时:
import lodashWrapped from 'myutils/lodash/debounce';
sinon.stub(lodashWrapped , 'debounce').callsFake((callbackFn) => {
// this is stubbed now
});
// go on, make your tests now