Rai*_*baz 12 javascript unit-testing qunit intersection-observer
我已(书面相当差)一个JavaScript组件在我的应用程序来处理无限滚动分页,我试图重写它使用的IntersectionObserver
,如所描述这里,但是我遇到在测试它的问题.
有没有办法在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
Run Code Online (Sandbox Code Playgroud)
我真的不喜欢这种方法,因为它暴露了组件IntersectionObserver
内部使用的事实,这是我认为客户端代码不应该看到的实现细节,所以有没有更好的方法来测试它?
奖金喜欢不使用jQuery的解决方案:)
Rob*_*uch 17
在jest.setup.js文件中,使用以下实现模拟 IntersectionObserver:
global.IntersectionObserver = class IntersectionObserver {
constructor() {}
disconnect() {
return null;
}
observe() {
return null;
}
takeRecords() {
return null;
}
unobserve() {
return null;
}
};
Run Code Online (Sandbox Code Playgroud)
除了使用Jest Setup File 之外,您还可以直接在测试中或在 beforeAll,beforeEach 块中进行此模拟。
Rob*_*ina 16
这是基于先前答案的另一种选择,您可以在beforeEach
方法内部或.test.js
文件开头运行它。
您还可以将参数传递给setupIntersectionObserverMock
以模拟observe
和/或unobserve
使用jest.fn()
模拟函数监视它们的方法。
/**
* Utility function that mocks the `IntersectionObserver` API. Necessary for components that rely
* on it, otherwise the tests will crash. Recommended to execute inside `beforeEach`.
* @param intersectionObserverMock - Parameter that is sent to the `Object.defineProperty`
* overwrite method. `jest.fn()` mock functions can be passed here if the goal is to not only
* mock the intersection observer, but its methods.
*/
export function setupIntersectionObserverMock({
root = null,
rootMargin = '',
thresholds = [],
disconnect = () => null,
observe = () => null,
takeRecords = () => [],
unobserve = () => null,
} = {}) {
class MockIntersectionObserver {
constructor() {
this.root = root;
this.rootMargin = rootMargin;
this.thresholds = thresholds;
this.disconnect = disconnect;
this.observe = observe;
this.takeRecords = takeRecords;
this.unobserve = unobserve;
}
}
Object.defineProperty(window, 'IntersectionObserver', {
writable: true,
configurable: true,
value: MockIntersectionObserver
});
Object.defineProperty(global, 'IntersectionObserver', {
writable: true,
configurable: true,
value: MockIntersectionObserver
});
}
Run Code Online (Sandbox Code Playgroud)
对于打字稿:
/**
* Utility function that mocks the `IntersectionObserver` API. Necessary for components that rely
* on it, otherwise the tests will crash. Recommended to execute inside `beforeEach`.
* @param intersectionObserverMock - Parameter that is sent to the `Object.defineProperty`
* overwrite method. `jest.fn()` mock functions can be passed here if the goal is to not only
* mock the intersection observer, but its methods.
*/
export function setupIntersectionObserverMock({
root = null,
rootMargin = '',
thresholds = [],
disconnect = () => null,
observe = () => null,
takeRecords = () => [],
unobserve = () => null,
} = {}): void {
class MockIntersectionObserver implements IntersectionObserver {
readonly root: Element | null = root;
readonly rootMargin: string = rootMargin;
readonly thresholds: ReadonlyArray < number > = thresholds;
disconnect: () => void = disconnect;
observe: (target: Element) => void = observe;
takeRecords: () => IntersectionObserverEntry[] = takeRecords;
unobserve: (target: Element) => void = unobserve;
}
Object.defineProperty(
window,
'IntersectionObserver', {
writable: true,
configurable: true,
value: MockIntersectionObserver
}
);
Object.defineProperty(
global,
'IntersectionObserver', {
writable: true,
configurable: true,
value: MockIntersectionObserver
}
);
}
Run Code Online (Sandbox Code Playgroud)
Kev*_*cke 10
由于我们正在使用 TypeScript 和 React (tsx) 的配置,因此没有任何已发布的回答对我有用。这是最终有效的方法:
beforeEach(() => {
// IntersectionObserver isn't available in test environment
const mockIntersectionObserver = jest.fn();
mockIntersectionObserver.mockReturnValue({
observe: () => null,
unobserve: () => null,
disconnect: () => null
});
window.IntersectionObserver = mockIntersectionObserver;
});
Run Code Online (Sandbox Code Playgroud)
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', () => {
...
})
});
Run Code Online (Sandbox Code Playgroud)
因此,我使用observe
(和disconnect
)方法创建了一个模拟对象,并覆盖IntersectionObserver
了窗口对象。根据您的用法,您可能必须覆盖其他功能(请参阅:https : //developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API#Browser_compatibility)
该代码受https://gist.github.com/ianmcnally/4b68c56900a20840b6ca840e2403771c启发,但未使用jest
归档时间: |
|
查看次数: |
2809 次 |
最近记录: |