从零开始的小程序单元测试实践(附有避免陷阱和源代码跟踪指南)
最编程
2024-04-20 16:49:34
...
components/user.js
) Component({
data: {
nickname: ''
},
methods: {
handleUserInfo: function(e) {
console.log(e);
}
}
})
npm run test
,可以看到事件还是成功触发了,不过detail
是{}
console.log components/user.js:21
{ type: 'getuserinfo',
timeStamp: 948,
target: { id: '', offsetLeft: 0, offsetTop: 0, dataset: {} },
currentTarget: { id: '', offsetLeft: 0, offsetTop: 0, dataset: {} },
detail: {},
touches: {},
changedTouches: {} }
dispatchEvent
方法是被测试组件的子组件
,被测试组件
由simulate.render
函数返回node_modules/miniprogram-simulate/src/index.js
,看到render函数(152行)
,可以看到返回的组件由jComponent.create
提供node_modules/j-component/src/index.js
的create
函数,可以看到其返回了RootComponent
实例,而RootComponent
是由./render/component.js
提供node_modules/j-component/src/render/component.js
的dispatchEvent
函数,在这里可以打下日志测试(本文就不打了,结果是这里的options就是user.spec.js
dispatchEvent
函数的第二个参数
,detail
是有值的)自定义事件
,所以会走到91行
的代码,该代码块如下:// 自定义事件
const customEvent = new CustomEvent(eventName, options);
// 模拟异步情况
setTimeout(() => {
dom.dispatchEvent(customEvent);
exparser.Event.dispatchEvent(customEvent.target, exparser.Event.create(eventName, {}, {
originalEvent: customEvent,
bubbles: true,
capturePhase: true,
composed: true,
extraFields: {
touches: options.touches || {},
changedTouches: options.changedTouches || {},
},
}));
}, 0);
exparser.Event.dispatchEvent
函数,该函数的第二个参数
调用了exparser.Event.create
对自定义事件进行了包装,这里还没到最底层,需要继续跟踪exparser
对象是miniprogram-exparser模块
提供的,浏览node_modules/miniprogram-exparser/exparser.min.js
,发现该文件被混淆了,不过没关系混淆后的代码逻辑是不变的,只不过变量名变得无意义,可读性变差
三个参数
的create
函数(Object.create不算
),需要有耐心,经过排查后发现168行代码应该是目标代码i.create = function(e, t, r) {
r = r || {};
var n = r.originalEvent, o = r.extraFields || {}, a = Date.now() - l, s = new i;
s.currentTarget = null, s.type = e, s.timeStamp = a, s.mark = null, s.detail = t, s.bubbles = !!r.bubbles, s.composed = !!r.composed, s.__originalEvent = n, s.__hasCapture = !!r.capturePhase, s.__stopped = !1, s.__dispatched = !1;
for (var u in o) s[u] = o[u];
return s;
}
s.detail = t
这个赋值,t
是create
的第二个参数
,由node_modules/j-component/render/component.js
的wxparser.Event.create
传入,但是传入的第二个参数写死了{}
,所以咱们的组件获取detail
的时候永远为{}
,将其修改为options.detail||{}
即可,修改后代码如下:exparser.Event.dispatchEvent(customEvent.target, exparser.Event.create(eventName, options.detail||{}, xxxxxx
PASS tests/components/user.spec.js