无法监视 window.confirm()
Unable to spy on window.confirm()
在我的 Angular 8 项目中,单击注销后,出现确认 window 并要求 Yes/No 注销。我想测试确认 window 是否出现。在我的spec.ts
里,我写了spyOn(window, 'confirm').and.returnValue(false);
。我不知道这是否正确。我需要两件事。首先,确认 window 是否出现;其次,如何使用 jasmine 来点击 'Yes' 选项。请帮忙。下面是我的代码:
header.component.ts
...
import { AuthenticationService } from '../../core/authentication.service';
...
@Component({
selector: 'app-header',
templateUrl: './header.component.html',
styleUrls: ['./header.component.css']
})
export class HeaderComponent implements OnInit {
legalName: any;
constructor(public authService: AuthenticationService, public accountService: AccountService, public router: Router) {}
ngOnInit() {
this.accountService.getTransactionHistory().subscribe((res) => {
res = JSON.parse(res);
this.legalName = res['Result'].array.RevTrxn[0].trxn.legalName;
})
}
signout() {
this.authService.signout();
}
authentication.service.ts
signout(){
var res = window.confirm("Are you Sure!")
if(res){
window.localStorage.removeItem('token');
this.router.navigate(['/login'])
}
}
header.component.spec.ts
import { HeaderComponent } from './header.component';
import { AuthenticationService } from 'src/app/core/authentication.service';
import { AccountService } from 'src/app/core/account.service';
import transactions from 'src/app/core/model/mock-transaction-history.json';
describe('HeaderComponent', () => {
let component: HeaderComponent;
let fixture: ComponentFixture<HeaderComponent>;
let debugElement: DebugElement;
let mockAuthService;
let mockAccountService;
let trans;
beforeEach(async(() => {
trans = transactions;
mockAccountService = jasmine.createSpyObj(['getTransactionHistory']);
mockAuthService = jasmine.createSpyObj(['signout']);
TestBed.configureTestingModule({
declarations: [HeaderComponent],
imports: [RouterTestingModule, HttpClientTestingModule],
providers: [
{ provide: AccountService, useValue: mockAccountService },
{ provide: AuthenticationService, useValue: mockAuthService },
],
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(HeaderComponent);
component = fixture.componentInstance;
debugElement = fixture.debugElement;
});
it('clicking on "Sign Out" should ask user to confirm', () => {
mockAccountService.getTransactionHistory.and.returnValue(of(JSON.stringify(trans)));
const callSignOut = mockAuthService.signout.and.returnValue([]);
spyOn(window, 'confirm').and.returnValue(false);
const signOut = debugElement.query(By.css('.sign-out'));
signOut.triggerEventHandler('click', {});
fixture.detectChanges();
expect(window.confirm).toHaveBeenCalled();
});
});
虽然 运行 这个,但我在 karma 控制台中得到 Expected spy confirm to have been called.
。我不知道为什么它没有被调用。我测试了 AuthenticationService
的 signout()
函数是否被调用。无论如何它都会被调用。如您所见,window.confirm()
方法位于 signout()
函数内。
测试时真的调用了你的服务实现吗?您正在注入服务模拟:
{ provide: AuthenticationService, useValue: mockAuthService },
然后在您的测试中模拟注销方法:
const callSignOut = mockAuthService.signout.and.returnValue([]);
所以在点击时,这不会按照您的要求调用您的服务方法:
signout() {
// This calls your mock service now.
this.authService.signout();
}
总的来说:我会创建一个 WindowService
returns window 对象。这使得在测试期间模拟 window 变得容易得多。
我会将我的反馈作为答案而不是评论,原因是,您进行单元测试的方式有点误导。
单元测试的思想是隔离每个文件(服务、组件、管道等),然后测试其功能。为了隔离,我们使用 use mocks。我看你做的很完美
现在,作为单元测试的一部分,您应该测试 this.authService.signout();
是否在 signout()
上被调用。 authService.signout()
调用 windows.confirm
是否应该是 AuthenticationService
.
单元测试的一部分
关于测试 window
对象的问题(对于您应该做的 service
),您需要创建 serviceWindowObj
并将 window
对象分配给它. window
对象。看一看。我想你可以从中得到一个想法。
干杯!
由于您不熟悉 Angular 的单元测试,请尝试 this article,它在底部包含更多链接以帮助您了解最佳实践
在我的 Angular 8 项目中,单击注销后,出现确认 window 并要求 Yes/No 注销。我想测试确认 window 是否出现。在我的spec.ts
里,我写了spyOn(window, 'confirm').and.returnValue(false);
。我不知道这是否正确。我需要两件事。首先,确认 window 是否出现;其次,如何使用 jasmine 来点击 'Yes' 选项。请帮忙。下面是我的代码:
header.component.ts
...
import { AuthenticationService } from '../../core/authentication.service';
...
@Component({
selector: 'app-header',
templateUrl: './header.component.html',
styleUrls: ['./header.component.css']
})
export class HeaderComponent implements OnInit {
legalName: any;
constructor(public authService: AuthenticationService, public accountService: AccountService, public router: Router) {}
ngOnInit() {
this.accountService.getTransactionHistory().subscribe((res) => {
res = JSON.parse(res);
this.legalName = res['Result'].array.RevTrxn[0].trxn.legalName;
})
}
signout() {
this.authService.signout();
}
authentication.service.ts
signout(){
var res = window.confirm("Are you Sure!")
if(res){
window.localStorage.removeItem('token');
this.router.navigate(['/login'])
}
}
header.component.spec.ts
import { HeaderComponent } from './header.component';
import { AuthenticationService } from 'src/app/core/authentication.service';
import { AccountService } from 'src/app/core/account.service';
import transactions from 'src/app/core/model/mock-transaction-history.json';
describe('HeaderComponent', () => {
let component: HeaderComponent;
let fixture: ComponentFixture<HeaderComponent>;
let debugElement: DebugElement;
let mockAuthService;
let mockAccountService;
let trans;
beforeEach(async(() => {
trans = transactions;
mockAccountService = jasmine.createSpyObj(['getTransactionHistory']);
mockAuthService = jasmine.createSpyObj(['signout']);
TestBed.configureTestingModule({
declarations: [HeaderComponent],
imports: [RouterTestingModule, HttpClientTestingModule],
providers: [
{ provide: AccountService, useValue: mockAccountService },
{ provide: AuthenticationService, useValue: mockAuthService },
],
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(HeaderComponent);
component = fixture.componentInstance;
debugElement = fixture.debugElement;
});
it('clicking on "Sign Out" should ask user to confirm', () => {
mockAccountService.getTransactionHistory.and.returnValue(of(JSON.stringify(trans)));
const callSignOut = mockAuthService.signout.and.returnValue([]);
spyOn(window, 'confirm').and.returnValue(false);
const signOut = debugElement.query(By.css('.sign-out'));
signOut.triggerEventHandler('click', {});
fixture.detectChanges();
expect(window.confirm).toHaveBeenCalled();
});
});
虽然 运行 这个,但我在 karma 控制台中得到 Expected spy confirm to have been called.
。我不知道为什么它没有被调用。我测试了 AuthenticationService
的 signout()
函数是否被调用。无论如何它都会被调用。如您所见,window.confirm()
方法位于 signout()
函数内。
测试时真的调用了你的服务实现吗?您正在注入服务模拟:
{ provide: AuthenticationService, useValue: mockAuthService },
然后在您的测试中模拟注销方法:
const callSignOut = mockAuthService.signout.and.returnValue([]);
所以在点击时,这不会按照您的要求调用您的服务方法:
signout() {
// This calls your mock service now.
this.authService.signout();
}
总的来说:我会创建一个 WindowService
returns window 对象。这使得在测试期间模拟 window 变得容易得多。
我会将我的反馈作为答案而不是评论,原因是,您进行单元测试的方式有点误导。
单元测试的思想是隔离每个文件(服务、组件、管道等),然后测试其功能。为了隔离,我们使用 use mocks。我看你做的很完美
现在,作为单元测试的一部分,您应该测试 this.authService.signout();
是否在 signout()
上被调用。 authService.signout()
调用 windows.confirm
是否应该是 AuthenticationService
.
关于测试 window
对象的问题(对于您应该做的 service
),您需要创建 serviceWindowObj
并将 window
对象分配给它. window
对象。看一看。我想你可以从中得到一个想法。
干杯!
由于您不熟悉 Angular 的单元测试,请尝试 this article,它在底部包含更多链接以帮助您了解最佳实践