在 Jasmine 中使用 2 个不同的 mock 进行测试
Testing with 2 different mocks in Jasmine
我有一个这样的 ts 守卫:
@Injectable({
providedIn: 'root'
})
export class AppEssentialsGuard implements CanActivate {
private readonly DEFAULT_APP_ID = 'def';
constructor(private appsService: AppsService) {}
canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
const url = this.getDefaultAppUrl();
if (url) {
window.open(url);
}
return false;
}
private getDefaultAppUrl(): string {
const myApp = this.appsService.getAllApps()
.find(app => app.appId === this.DEFAULT_APP_ID);
return myApp ? myApp.url : null;
}
}
我正在为它编写如下测试:
describe('AppEssentialsGuard', () => {
let guard: AppEssentialsGuard;
let appsService: AppsService;
beforeEach(() => {
TestBed.configureTestingModule({
providers: [
mockProvider(RequesterService),
{provide: AppsService, useClass: AppsServiceMock}
]
});
appsService = TestBed.inject(AppsService);
guard = TestBed.inject(AppEssentialsGuard);
});
it('should be created', () => {
expect(guard).toBeTruthy();
});
it( 'should open new default app window', () => {
spyOn(window, 'open');
let returnValue = guard.canActivate(null, null);
expect( window.open ).toHaveBeenCalledWith("https://appstore.com/");
expect(returnValue).toBeFalsy();
});
});
现在为了快乐流程测试,我正在使用 useClass 中指定的 AppsServiceMock,其中 returns 一组虚拟应用程序,包括 ID 为 'def' 的应用程序,以便测试通过。
我的问题是,我还想测试这个 url returns 一个空数组,或者没有 'def' 应用程序的情况,我该如何测试这两种情况?我不知道如何使用另一个模拟
我是 Jasmine 的新手
谢谢!
您可以通过在进行断言之前监视 getAllApps
和 return 值来实现您正在寻找的行为。监视和 return 一个值会忽略原始细节实现,并且将始终 return 您指定的值。
// happy path;
it( 'should open new default app window', () => {
spyOn(appService, 'getAllApps').and.returnValue([/* add an array of elements you would like */]);
spyOn(window, 'open');
let returnValue = guard.canActivate(null, null);
expect( window.open ).toHaveBeenCalledWith("https://appstore.com/");
expect(returnValue).toBeFalsy();
});
// empty array path
it( 'should not open new default app window', () => {
spyOn(appService, 'getAllApps').and.returnValue([]);
spyOn(window, 'open');
let returnValue = guard.canActivate(null, null);
expect( window.open ).not.toHaveBeenCalled(); // change your assertion here
expect(returnValue).toBeFalsy();
});
我有一个这样的 ts 守卫:
@Injectable({
providedIn: 'root'
})
export class AppEssentialsGuard implements CanActivate {
private readonly DEFAULT_APP_ID = 'def';
constructor(private appsService: AppsService) {}
canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
const url = this.getDefaultAppUrl();
if (url) {
window.open(url);
}
return false;
}
private getDefaultAppUrl(): string {
const myApp = this.appsService.getAllApps()
.find(app => app.appId === this.DEFAULT_APP_ID);
return myApp ? myApp.url : null;
}
}
我正在为它编写如下测试:
describe('AppEssentialsGuard', () => {
let guard: AppEssentialsGuard;
let appsService: AppsService;
beforeEach(() => {
TestBed.configureTestingModule({
providers: [
mockProvider(RequesterService),
{provide: AppsService, useClass: AppsServiceMock}
]
});
appsService = TestBed.inject(AppsService);
guard = TestBed.inject(AppEssentialsGuard);
});
it('should be created', () => {
expect(guard).toBeTruthy();
});
it( 'should open new default app window', () => {
spyOn(window, 'open');
let returnValue = guard.canActivate(null, null);
expect( window.open ).toHaveBeenCalledWith("https://appstore.com/");
expect(returnValue).toBeFalsy();
});
});
现在为了快乐流程测试,我正在使用 useClass 中指定的 AppsServiceMock,其中 returns 一组虚拟应用程序,包括 ID 为 'def' 的应用程序,以便测试通过。
我的问题是,我还想测试这个 url returns 一个空数组,或者没有 'def' 应用程序的情况,我该如何测试这两种情况?我不知道如何使用另一个模拟
我是 Jasmine 的新手
谢谢!
您可以通过在进行断言之前监视 getAllApps
和 return 值来实现您正在寻找的行为。监视和 return 一个值会忽略原始细节实现,并且将始终 return 您指定的值。
// happy path;
it( 'should open new default app window', () => {
spyOn(appService, 'getAllApps').and.returnValue([/* add an array of elements you would like */]);
spyOn(window, 'open');
let returnValue = guard.canActivate(null, null);
expect( window.open ).toHaveBeenCalledWith("https://appstore.com/");
expect(returnValue).toBeFalsy();
});
// empty array path
it( 'should not open new default app window', () => {
spyOn(appService, 'getAllApps').and.returnValue([]);
spyOn(window, 'open');
let returnValue = guard.canActivate(null, null);
expect( window.open ).not.toHaveBeenCalled(); // change your assertion here
expect(returnValue).toBeFalsy();
});