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?

如果 myGraphDtoit 中可见,只需执行下一步

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(),这会导致我出错。