我在我的应用程序中有一个(相当糟糕的)javascript组件处理无限滚动分页,我正在尝试重写它以使用IntersectionObserver
,如here所述,但是我在测试它时遇到问题。
有没有办法在QUnit测试中驱动观察者的行为,即用我的测试中描述的一些条目触发观察者回调?
我提出的一个可能的解决方案是在组件的原型中公开回调函数,并在我的测试中直接调用它,如下所示:
InfiniteScroll.prototype.observerCallback = function(entries) {
//handle the infinite scroll
}
InfiniteScroll.prototype.initObserver = function() {
var io = new IntersectionObserver(this.observerCallback);
io.observe(someElements);
}
//In my test
var component = new InfiniteScroll();
component.observerCallback(someEntries);
//Do some assertions about the state after the callback has been executed
我真的不喜欢这种方法,因为它暴露了组件内部使用IntersectionObserver
的事实,这是我认为客户端代码不应该看到的实现细节,所以有没有更好的方法来测试它?
奖金喜欢不使用jQuery的解决方案:)
同样的问题在2019年这是我解决它的方式:
import ....
describe('IntersectionObserverMokTest', () => {
...
const observeMock = {
observe: () => null,
disconnect: () => null // maybe not needed
};
beforeEach(async(() => {
(<any> window).IntersectionObserver = () => observeMock;
....
}));
if(' should run the Test without throwing an error for the IntersectionObserver', () => {
...
})
});
所以我创建了一个模拟对象,使用observe
(和disconnect
)方法并覆盖窗口对象上的IntersectionObserver
。根据您的使用情况,您可能必须覆盖其他功能(请参阅:https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API#Browser_compatibility)
该代码的灵感来自https://gist.github.com/ianmcnally/4b68c56900a20840b6ca840e2403771c但不使用jest
在您的jest.setup.js文件中,使用以下实现模拟IntersectionObserver:
global.IntersectionObserver = class IntersectionObserver {
constructor() {}
observe() {
return null;
}
unobserve() {
return null;
}
};
您可以直接在测试中或在之前的每个块中使用Jest Setup File,而不是使用qazxswpoi。