fab*_*i_k 9 unit-testing chromium jasmine karma-jasmine angular
我有一个 BreakpointService,它告诉我 - 取决于屏幕宽度 - 我应该在哪个 SidebarMode(关闭 - 缩小 - 打开)中显示我的侧边栏。
这是服务的主要部分:
constructor(private breakpointObserver: BreakpointObserver) {
this.closed$ = this.breakpointObserver.observe(['(min-width: 1024px)']).pipe(
filter((state: BreakpointState) => !state.matches),
mapTo(SidebarMode.Closed)
);
this.opened$ = this.breakpointObserver.observe(['(min-width: 1366px)']).pipe(
filter((state: BreakpointState) => state.matches),
mapTo(SidebarMode.Open)
);
const minifiedStart$: Observable<boolean> = this.breakpointObserver.observe(['(min-width: 1024px)']).pipe(map(state => state.matches));
const minifiedEnd$: Observable<boolean> = this.breakpointObserver.observe(['(max-width: 1366px)']).pipe(map(state => state.matches));
this.minified$ = minifiedStart$.pipe(
flatMap(start => minifiedEnd$.pipe(map(end => start && end))),
distinctUntilChanged(),
filter(val => val === true),
mapTo(SidebarMode.Minified)
);
this.observer$ = merge(this.closed$, this.minified$, this.opened$);
}
Run Code Online (Sandbox Code Playgroud)
通过这一行,我可以订阅事件:
this.breakpointService.observe().subscribe();
Run Code Online (Sandbox Code Playgroud)
现在,我想在单元测试中测试不同的模式,但我不知道
如何在测试中模拟 window.screen.width 属性
我尝试了几件事,但对我来说没有任何效果。
到目前为止,这是我的测试设置:
describe('observe()', () => {
function resize(width: number): void {
// did not work
// window.resizeTo(width, window.innerHeight);
// (<any>window).screen = { width: 700 };
// spyOn(window, 'screen').and.returnValue(...)
}
let currentMode;
beforeAll(() => {
service.observe().subscribe(mode => (currentMode = mode));
});
it('should return Observable<SidebarMode>', async () => {
resize(1000);
expect(Object.values(SidebarMode).includes(SidebarMode[currentMode])).toBeTruthy();
});
xit('should return SidebarMode.Closed', async () => {
resize(600);
expect(currentMode).toBe(SidebarMode.Closed);
});
xit('should return SidebarMode.Minified', async () => {
resize(1200);
expect(currentMode).toBe(SidebarMode.Minified);
});
xit('should return SidebarMode.Open', async () => {
resize(2000);
expect(currentMode).toBe(SidebarMode.Open);
});
});
Run Code Online (Sandbox Code Playgroud)
小智 12
我猜 BreakPointObserver 会监听 resize 事件,所以也许您可以尝试使用 jasmine 模拟 window.innerWidth / window.outerWidth 之类的东西?
spyOnProperty(window, 'innerWidth').and.returnValue(760);
然后您手动触发调整大小事件:
window.dispatchEvent(new Event('resize'));
它看起来像这样:
it('should mock window inner width', () => {
spyOnProperty(window, 'innerWidth').and.returnValue(760);
window.dispatchEvent(new Event('resize'));
});
Run Code Online (Sandbox Code Playgroud)
BreakpointObserver
我猜你不是真的想模拟 window.screen,你实际上想模拟BreakpointObserver
. 毕竟,不需要测试他们的代码,您只想测试您的代码是否正确响应BreakpointObserver.observe()
不同屏幕尺寸返回的 observable 。
有很多不同的方法可以做到这一点。为了说明一种方法,我将STACKBLITZ与您的代码放在一起,展示了我将如何处理此问题。与上面的代码不同的注意事项:
resize()
发生在service = TestBed.get(MyService);
调用之前。BreakpointObserver
用 spyObj 进行了模拟,并调用了一个假函数来代替该BreakpointObserver.observe()
方法。这个假函数使用了我设置的过滤器,其中包含我想要的各种匹配结果。它们都以 false 开头,因为这些值会根据需要模拟的屏幕尺寸而改变,而这是由resize()
您在上面的代码中使用的函数设置的。注意:当然还有其他方法可以解决这个问题。
breakpoints-observer.spec.ts
在 github 上查看自己的角度材料。这是一种比我在这里概述的更好的通用方法,它只是为了测试您提供的功能。
这是来自 StackBlitz 的新建议describe
函数的片段:
describe(MyService.name, () => {
let service: MyService;
const matchObj = [
// initially all are false
{ matchStr: '(min-width: 1024px)', result: false },
{ matchStr: '(min-width: 1366px)', result: false },
{ matchStr: '(max-width: 1366px)', result: false },
];
const fakeObserve = (s: string[]): Observable<BreakpointState> =>
from(matchObj).pipe(
filter(match => match.matchStr === s[0]),
map(match => ({ matches: match.result, breakpoints: {} })),
);
const bpSpy = jasmine.createSpyObj('BreakpointObserver', ['observe']);
bpSpy.observe.and.callFake(fakeObserve);
beforeEach(() => {
TestBed.configureTestingModule({
imports: [],
providers: [MyService, { provide: BreakpointObserver, useValue: bpSpy }],
});
});
it('should be createable', () => {
service = TestBed.inject(MyService);
expect(service).toBeTruthy();
});
describe('observe()', () => {
function resize(width: number): void {
matchObj[0].result = width >= 1024;
matchObj[1].result = width >= 1366;
matchObj[2].result = width <= 1366;
}
it('should return Observable<SidebarMode>', () => {
resize(1000);
service = TestBed.inject(MyService);
service.observe().subscribe(mode => {
expect(
Object.values(SidebarMode).includes(SidebarMode[mode]),
).toBeTruthy();
});
});
it('should return SidebarMode.Closed', () => {
resize(600);
service = TestBed.inject(MyService);
service
.observe()
.subscribe(mode => expect(mode).toBe(SidebarMode.Closed));
});
it('should return SidebarMode.Minified', () => {
resize(1200);
service = TestBed.inject(MyService);
service
.observe()
.subscribe(mode => expect(mode).toBe(SidebarMode.Minified));
});
it('should return SidebarMode.Open', () => {
resize(2000);
service = TestBed.inject(MyService);
service.observe().subscribe(mode => expect(mode).toBe(SidebarMode.Open));
});
});
});
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
7959 次 |
最近记录: |