Angular 如何在不同的单元测试中更新模拟数据
Angular How to update mock data in different unit tests
describe('landing component', () => {
beforeEach(() => {
mockAccountService = new Mock<AccountService>({
getSelectedContractAccountNumber: () => {
return testAccountNumber;
}
});
myGraphDto = <any>{
accountsById: {
[testAccountNumber]: {
flybuys: {
cardNumber: testFlybuysCardNumber,
confirmationStatus: 'PendingConfirmation'
},
contracts: {
[0]: {
isResidentialCustomer: true
}
}
}
}
};
mockGraphService = new Mock<GraphService>({
getData: () => {
return of(myGraphDto);
}
});
TestBed.configureTestingModule({
providers: [
{ provide: IAccountServiceMA, useValue: mockAccountService.Object },
{ provide: GraphService, useValue: mockGraphService.Object }
],
imports: [myModule, RouterTestingModule.withRoutes([])]
});
fixture = TestBed.createComponent(LandingComponent);
myComponent = fixture.componentInstance;
router = TestBed.get(Router);
spyOn(router, 'navigate');
fixture.detectChanges();
});
it('should display for residential customers', (done: DoneFn) => {
myComponent.isResidentialCustomer();
const price = fixture.nativeElement.querySelector('.landing-price');
fixture.detectChanges();
expect(price.textContent).toBe('');
done();
});
it('should display for SME', (done: DoneFn) => {
// How do I update the isResidentialCustomer to false here?
const price = fixture.nativeElement.querySelector('.landing-price');
console.log('-----------------------------price--------------------------------');
console.log(price);
expect(price.textContent).toBe('');
done();
});
如何在第二次单元测试中将 isResidentialCustomer 更新为 false?
如果 myGraphDto
在 it
中可见,只需执行下一步
myGraphDto.accountsById[testAccountNumber].contracts[0].isResidentialCustomer = true;
fixture.detectChanges();
如果使用OnPush
,那么只需使用myGraphDto.accountsById = JSON.parse(JSON.stringify(myGraphDto.accountsById))
摇动对象的所有节点即可。
如果还不够,创建一个在 describe
块中可见的 BehaviorSubject
并使用它
behaviorSubject = new BehaviorSubject(myGraphDto);
mockGraphService = new Mock<GraphService>({
getData: behaviorSubject,
在it
你可以做到
behaviorSubject.next(updatedGraphDto);
fixture.detectChanges();
否则您需要使其任何部分可见才能访问测试中的值。
describe('landing component', () => {
let contract: any; // add this
beforeEach(() => {
mockAccountService = new Mock<AccountService>({
getSelectedContractAccountNumber: () => {
return testAccountNumber;
}
});
// add this
contract = {
isResidentialCustomer: true
};
myGraphDto = <any>{
accountsById: {
[testAccountNumber]: {
flybuys: {
cardNumber: testFlybuysCardNumber,
confirmationStatus: 'PendingConfirmation'
},
contracts: {
[0]: contract
}
}
}
};
mockGraphService = new Mock<GraphService>({
getData: () => {
return of(myGraphDto);
}
});
TestBed.configureTestingModule({
providers: [
{ provide: IAccountServiceMA, useValue: mockAccountService.Object },
{ provide: GraphService, useValue: mockGraphService.Object }
],
imports: [myModule, RouterTestingModule.withRoutes([])]
});
fixture = TestBed.createComponent(LandingComponent);
myComponent = fixture.componentInstance;
router = TestBed.get(Router);
spyOn(router, 'navigate');
fixture.detectChanges();
});
it('should display for residential customers', (done: DoneFn) => {
myComponent.isResidentialCustomer();
const price = fixture.nativeElement.querySelector('.landing-price');
fixture.detectChanges();
expect(price.textContent).toBe('');
done();
});
it('should display for SME', (done: DoneFn) => {
// How do I update the isResidentialCustomer to false here?
// add this.
contract.isResidentialCustomer = false;
fixture.detectChanges();
const price = fixture.nativeElement.querySelector('.landing-price');
console.log('-----------------------------price--------------------------------');
console.log(price);
expect(price.textContent).toBe('');
done();
});
我通过使用 ngFactory 和 .extend() 方法解决了这个问题
这是我更改的内容:
it('should display for SME', () => {
myGraphDto = <any>{
accountsById: {
[testAccountNumber]: {
flybuys: {
cardNumber: testFlybuysCardNumber,
confirmationStatus: 'PendingConfirmation'
},
contracts: {
[0]: {
isResidentialCustomer: false
}
}
}
}
};
mockGraphService.extend({ getData: () => of(myGraphDto) });
fixture.detectChanges();
expect(fixture.nativeElement.querySelector('.landing__price').textContent).toBe('');
});
此外,将 Testbed 更改为 useFactory 而不是 useValue
{ provide: GraphService, useFactory: () => mockGraphService.Object },
不要忘记在 it() 中使用 fixture.detectChanges(),不要在 Testbed 之后的 beforeEach() 中使用 fixture.detectChanges(),这会导致我出错。
describe('landing component', () => {
beforeEach(() => {
mockAccountService = new Mock<AccountService>({
getSelectedContractAccountNumber: () => {
return testAccountNumber;
}
});
myGraphDto = <any>{
accountsById: {
[testAccountNumber]: {
flybuys: {
cardNumber: testFlybuysCardNumber,
confirmationStatus: 'PendingConfirmation'
},
contracts: {
[0]: {
isResidentialCustomer: true
}
}
}
}
};
mockGraphService = new Mock<GraphService>({
getData: () => {
return of(myGraphDto);
}
});
TestBed.configureTestingModule({
providers: [
{ provide: IAccountServiceMA, useValue: mockAccountService.Object },
{ provide: GraphService, useValue: mockGraphService.Object }
],
imports: [myModule, RouterTestingModule.withRoutes([])]
});
fixture = TestBed.createComponent(LandingComponent);
myComponent = fixture.componentInstance;
router = TestBed.get(Router);
spyOn(router, 'navigate');
fixture.detectChanges();
});
it('should display for residential customers', (done: DoneFn) => {
myComponent.isResidentialCustomer();
const price = fixture.nativeElement.querySelector('.landing-price');
fixture.detectChanges();
expect(price.textContent).toBe('');
done();
});
it('should display for SME', (done: DoneFn) => {
// How do I update the isResidentialCustomer to false here?
const price = fixture.nativeElement.querySelector('.landing-price');
console.log('-----------------------------price--------------------------------');
console.log(price);
expect(price.textContent).toBe('');
done();
});
如何在第二次单元测试中将 isResidentialCustomer 更新为 false?
如果 myGraphDto
在 it
中可见,只需执行下一步
myGraphDto.accountsById[testAccountNumber].contracts[0].isResidentialCustomer = true;
fixture.detectChanges();
如果使用OnPush
,那么只需使用myGraphDto.accountsById = JSON.parse(JSON.stringify(myGraphDto.accountsById))
摇动对象的所有节点即可。
如果还不够,创建一个在 describe
块中可见的 BehaviorSubject
并使用它
behaviorSubject = new BehaviorSubject(myGraphDto);
mockGraphService = new Mock<GraphService>({
getData: behaviorSubject,
在it
你可以做到
behaviorSubject.next(updatedGraphDto);
fixture.detectChanges();
否则您需要使其任何部分可见才能访问测试中的值。
describe('landing component', () => {
let contract: any; // add this
beforeEach(() => {
mockAccountService = new Mock<AccountService>({
getSelectedContractAccountNumber: () => {
return testAccountNumber;
}
});
// add this
contract = {
isResidentialCustomer: true
};
myGraphDto = <any>{
accountsById: {
[testAccountNumber]: {
flybuys: {
cardNumber: testFlybuysCardNumber,
confirmationStatus: 'PendingConfirmation'
},
contracts: {
[0]: contract
}
}
}
};
mockGraphService = new Mock<GraphService>({
getData: () => {
return of(myGraphDto);
}
});
TestBed.configureTestingModule({
providers: [
{ provide: IAccountServiceMA, useValue: mockAccountService.Object },
{ provide: GraphService, useValue: mockGraphService.Object }
],
imports: [myModule, RouterTestingModule.withRoutes([])]
});
fixture = TestBed.createComponent(LandingComponent);
myComponent = fixture.componentInstance;
router = TestBed.get(Router);
spyOn(router, 'navigate');
fixture.detectChanges();
});
it('should display for residential customers', (done: DoneFn) => {
myComponent.isResidentialCustomer();
const price = fixture.nativeElement.querySelector('.landing-price');
fixture.detectChanges();
expect(price.textContent).toBe('');
done();
});
it('should display for SME', (done: DoneFn) => {
// How do I update the isResidentialCustomer to false here?
// add this.
contract.isResidentialCustomer = false;
fixture.detectChanges();
const price = fixture.nativeElement.querySelector('.landing-price');
console.log('-----------------------------price--------------------------------');
console.log(price);
expect(price.textContent).toBe('');
done();
});
我通过使用 ngFactory 和 .extend() 方法解决了这个问题
这是我更改的内容:
it('should display for SME', () => {
myGraphDto = <any>{
accountsById: {
[testAccountNumber]: {
flybuys: {
cardNumber: testFlybuysCardNumber,
confirmationStatus: 'PendingConfirmation'
},
contracts: {
[0]: {
isResidentialCustomer: false
}
}
}
}
};
mockGraphService.extend({ getData: () => of(myGraphDto) });
fixture.detectChanges();
expect(fixture.nativeElement.querySelector('.landing__price').textContent).toBe('');
});
此外,将 Testbed 更改为 useFactory 而不是 useValue
{ provide: GraphService, useFactory: () => mockGraphService.Object },
不要忘记在 it() 中使用 fixture.detectChanges(),不要在 Testbed 之后的 beforeEach() 中使用 fixture.detectChanges(),这会导致我出错。