我正在尝试编写一个单元测试,以检查在angular 8应用程序中是否调用了组件的onConfirm方法。我目前遇到错误
Error: Expected spy onConfirm to have been called.
我已经试图监视onConfirm,所以不确定为什么我收到上述错误消息。我已经共享了所有可能的代码来帮助诊断问题
单元测试
describe('SettlementAccountsComponent', () => {
let component: SettlementAccountsComponent;
let fixture: ComponentFixture<SettlementAccountsComponent>;
let alertService: AlertService;
let clientService: ClientService;
let confirmModal: ConfirmModalComponent;
class MockClientService {
getNumberOfTradesWhereOPIIsSetOn(clientCompanyOpiId: number) {
// return of(this.getNumberOfTradesWhereOPIIsSetOn);
}
deleteSettlementAccount(clientCompanyOpiId: number, authUserId: number) {
// return of(this.deleteSettlementAccount)
}
}
@Component({
selector: 'settlement-accounts'
})
class MockConfirmModalComponent{
openModal(title: string, message: string, data: any) {}
closeModal() { }
ngOnInit() {
}
ngAfterViewInit() {
}
public Confirm() {
}
}
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [
HttpClientModule,
RouterTestingModule,
FormsModule,
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
useClass: TranslateLanguageLoader
}
})
],
declarations: [
SettlementAccountsComponent,
AccountEditorModalComponent,
SetDefaultComponent,
ModalDirective
],
providers: [
AuthService,
AlertService,
ConfigurationService,
LocalStoreManager,
AppTitleService,
AppTranslationService,
NotificationService,
NotificationEndpoint,
EndpointFactory,
ClientEndpoint,
[{ provide: ClientService, useClass: MockClientService }],
[{ provide: ConfirmModalComponent, useClass: MockConfirmModalComponent }]
],
schemas: [NO_ERRORS_SCHEMA]
})
.compileComponents();
}));
beforeEach(() => {
//This gives default constructor
//use this if constructor calls other methods especially private
function getMockInstance(classToMock: any) {
// Save current class prototype
var oldPrototype = classToMock.prototype;
// Create empty type and copy the saved prototype
var newClass = function () {
return;
};
newClass.prototype = oldPrototype;
// Create a mock of the new class (empty constructor with same functions as classToMock)
var newInstance = new newClass();
return TypeMoq.Mock.ofInstance(newInstance);
}
const authServiceMock: TypeMoq.IMock<AuthService> = getMockInstance(AuthService);
authServiceMock.setup(x => x.currentUser)
.returns(() =>
new User('42', 'Chuck Norris', null, null, null, null, 1, null, null, null, null));
const localStoreMock: TypeMoq.IMock<LocalStoreManager> = TypeMoq.Mock.ofType(LocalStoreManager);
// localStoreMock.setup(x => x.getInitEvent())
// .returns(() => Observable.pipe(of()));
clientService = TestBed.get(ClientService);
confirmModal = TestBed.get(ConfirmModalComponent);
component = new SettlementAccountsComponent(
alertService
, clientService
, authServiceMock.object)
});
fit('onConfirm should be called', () => {
let clientCompanyOpiId = 10;
let testConfirmModal = ({
title: 'Delete Settlement Account',
message: 'Are you sure you want to delete this OPI account?'
} as ConfirmModalComponent);
component.confirmModal = testConfirmModal;
accounts: SettlementAccountModel[0];
this.accounts = [110,1796,15,'GBP'];
component.accounts = this.accounts;
component.accounts.length = 1;
spyOn(component, 'removeSettlementConfirmation').and.returnValue("mock response");
spyOn(clientService, 'getNumberOfTradesWhereOPIIsSetOn').and.returnValue("test");
spyOn(clientService, 'deleteSettlementAccount').and.callThrough();
spyOn(component, 'onConfirm').and.callThrough();
//component.onConfirm(clientCompanyOpiId);
expect(component.onConfirm).toHaveBeenCalled();
//expect(component.confirmModal).toBeTruthy();
});
确认模式
import { Component, OnInit, AfterViewInit, ViewChild, Injectable, EventEmitter, Output } from '@angular/core';
import { AlertService } from '../../../services/alert.service';
import { ModalDirective } from 'ngx-bootstrap/modal';
@Component({
selector: 'app-confirm-modal',
templateUrl: './confirm-modal.component.html'
})
@Injectable()
export class ConfirmModalComponent implements OnInit, AfterViewInit {
public title: string;
public message: string;
public data: any;
public isLoading: boolean;
@Output() onConfirm: EventEmitter<any> = new EventEmitter();
@ViewChild('confirmModal' , {static: false})
confirmModal: ModalDirective;
constructor(private alertService: AlertService) {
}
ngOnInit() {
this.alertService.resetStickyMessage();
}
ngAfterViewInit() {
this.confirmModal.hide();
}
public openModal(title: string, message: string, data: any) {
this.title = title;
this.message = message;
this.data = data;
this.confirmModal.show();
}
public Confirm() {
this.onConfirm.emit(this.data);
}
public closeModal() {
this.confirmModal.hide();
}
}
SettlementAccountComponent
import { Component, ViewChild, OnInit } from "@angular/core";
import { AlertService, MessageSeverity } from '../../services/alert.service';
import { ClientService } from '../../services/client/client.service';
import { AuthService } from '../../services/auth.service';
import { ClientCompanyVM, ClientCompanyAccountVM } from '../../models/client/client.models';
import { AccountEditorModalComponent } from './account-editor/account-editor-modal.component';
import { ModalDirective } from 'ngx-bootstrap/modal';
import { SettlementAccountModel } from "../../models/client/settlement-account.model";
import { SetDefaultComponent } from "./set-default/set-default.component";
import { ConfirmModalComponent } from "../shared/confirm-modal/confirm-modal.component";
@Component({
selector: 'settlement-accounts',
templateUrl: './settlement-accounts.component.html',
styleUrls: ['./settlement-accounts.component.css']
})
export class SettlementAccountsComponent implements OnInit {
clientCompany: ClientCompanyVM;
accounts: SettlementAccountModel[];
constructor(private alertService: AlertService
, private clientService: ClientService
, private authService: AuthService) {
this.clientCompany = new ClientCompanyVM();
}
@ViewChild(AccountEditorModalComponent , {static: false})
editorModal: AccountEditorModalComponent;
@ViewChild(SetDefaultComponent , {static: false})
setDefaultModal: SetDefaultComponent;
@ViewChild(ConfirmModalComponent, { static: false })
confirmModal: ConfirmModalComponent;
ngOnInit() {
this.alertService.resetStickyMessage();
this.clientService.getClientCompany(this.authService.currentUser.clientCompanyId)
.subscribe(
data => {
this.clientCompany = data;
},
error => {
this.alertService.showMessage("Error", "Unable to get Client Company Name", MessageSeverity.error)
});
this.getClientCompanyAccounts();
}
private getClientCompanyAccounts() {
this.clientService.getClientCompanyAccounts(this.authService.currentUser.clientCompanyId)
.subscribe(
data => {
this.accounts = data;
},
error => {
this.alertService.showMessage("Error", "Unable to get Client Company Accounts", MessageSeverity.error)
});
}
onAccountSubmitted() {
this.getClientCompanyAccounts();
}
onAccountSetDefault() {
this.getClientCompanyAccounts();
}
newAccountBoxDisplay() {
this.editorModal.newAccountBox();
}
editAccountBoxDisplay(id: number) {
this.editorModal.editAccountBox(id);
}
preventClick(event) {
event.preventDefault();
}
removeSettlementConfirmation(clientCompanyOpiId: number): void {
this.clientService.getNumberOfTradesWhereOPIIsSetOn(clientCompanyOpiId)
.subscribe(
data => {
const assignedTrades = data;
const trades = +assignedTrades > 1 ? 's' : '';
const message = assignedTrades
? `This OPI account is set on ${assignedTrades} trade${trades}. Are you sure you want to delete it?`
: `Are you sure you want to delete this OPI account?`;
const title = `Delete Settlement Account`;
this.confirmModal.openModal(title, message, clientCompanyOpiId);
},
error => {
this.alertService.showMessage("Error", "Unable to get Associated Trades for Settlement Account", MessageSeverity.error);
});
}
onConfirm(clientCompanyOpiId: number) {
if (this.accounts.length > 0 && clientCompanyOpiId) {
this.clientService.deleteSettlementAccount(clientCompanyOpiId, this.authService.currentUser.authUserId)
.subscribe(
data => {
const accountId = this.accounts.indexOf(this.accounts.find(obj => obj.clientCompanyOpiId === clientCompanyOpiId));
this.accounts.splice(accountId, 1);
},
error => {
this.alertService.showMessage("Error", "Unable to delete Settlement Account", MessageSeverity.error);
});
}
this.confirmModal.closeModal();
}
}
答案 0 :(得分:0)
您的测试已设置了Spy,但未调用函数。
点击按钮(大概有一个确认按钮),测试应该通过。
或者您可以添加
component.onConfirm(42);
直到测试结束,这也应该起作用