无法监视window.confirm()



在我的Angular 8项目中,单击注销时,会出现一个确认窗口,询问是否注销。我想测试确认窗口是否出现。在我的spec.ts中,我写了spyOn(window, 'confirm').and.returnValue(false);。我不知道这是否正确。我需要两样东西。首先,确认窗口是否出现;其次,如何使用jasmine点击"是"选项。请帮忙。以下是我的代码:

头组件.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'])
    } 
  }

头组件规格

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();
  });
});

在运行这个过程中,我在因果报应控制台中获得了Expected spy confirm to have been called.。我不知道为什么没有人叫它。我测试了AuthenticationServicesignout()函数是否被调用。不管怎么说,它正在被调用。如您所见,window.confirm()方法位于signout()函数内部。

我会把我的反馈作为一个答案,而不是一个评论,因为你做单元测试的方式有点误导。

单元测试的思想是隔离每个文件(服务、组件、管道等(,然后测试其功能。为了隔离,我们使用mock。我看得出来你做得很完美。

现在,作为单元测试的一部分,您应该测试是否在signout()上调用了this.authService.signout();authService.signout()是否调用windows.confirm应该是AuthenticationService单元测试的一部分。

关于测试window对象的问题(对于您的service,您应该这样做(,您需要创建serviceWindowObj并将window对象分配给它。我已经讨论了替换window对象的类似问题。看一看。我想你可以从中得到一个想法。

干杯!


由于您是Angular单元测试的新手,请尝试这篇文章,它在底部还包含几个链接,可以帮助您了解最佳实践

您的服务实现在测试期间真的被调用了吗?您正在注入一个服务模拟:

{ provide: AuthenticationService, useValue: mockAuthService },

然后在测试中模拟签出方法:

const callSignOut = mockAuthService.signout.and.returnValue([]);

因此,点击后,这不会按照您的要求调用您的服务方法:

signout() {
    // This calls your mock service now.
    this.authService.signout();
}

一般来说:我将创建一个返回窗口对象的WindowService。这使得在测试期间模拟窗口变得容易得多。

最新更新