Como zombar da função de serviço em componente Angular para o ensaio unitário

estou a escrever um teste de unidade para aplicação angular, estou a testar se a função de serviço devolve um valor.

componente.especificacao.ts

import {TopToolBarService} from '../../top-toolbar/top-toolbar.service';

beforeEach(async(() => {
   TestBed.configureTestingModule ({
   declarations: [ UsersListComponent],
   providers: [TopToolBarService],//tried mocking service here,still test failed
   schemas:[CUSTOM_ELEMENTS_SCHEMA]
 })
  .compileComponents();
}));



beforeEach(() => {
    fixture = TestBed.createComponent(UserListComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });



  it('should return data from service function', async(() => {
    let mockTopToolBarService: jasmine.SpyObj<TopToolBarService>;
    mockTopToolBarService = jasmine.createSpyObj('TopToolBarService', ['getCustomer']);
    mockTopToolBarService.getCustomer.and.returnValue("king");
    fixture.detectChanges();
    expect(component.bDefine).toBe(true); //fails
  }))

componente.ts

bDefine = false;
ngOnInit() {
 let customer = this.topToolBarService.getCustomer();
 if (customer == null) {
   bDefine = false;
 } else {
    bDefine = true;
   }
}

acredito que troquei da função de serviço no meu teste, por isso espero que tenha chegado a outra parte onde a variável é definida como 'verdadeira'.

Serviço Topto-Bar.ts

import { EventEmitter, Injectable, Output } from "@angular/core";

@Injectable()
export class TopToolBarService {
customer = null;

  getCustomer() {
    return this.customer;
  }
}
Author: karansys, 2019-10-10

4 answers

Tente actualizar os fornecedores no interior de Before aach[async (()=>...) e movendo a sua variável de serviço simulado em cima dela:

describe('Component TEST', () => {
   ...
   let mockToolBarService;
   ...
      beforeEach(async(() => {
      ...
      mockToolBarService = jasmine.createSpyObj(['getCustomer']);
      mockToolBarService.getCustomer.and.returnValue('king');
      TestBed.configureTestingModule ({
           ...
           providers: [ { provide: TopToolBarService, useValue: mockToolBarService } ]
           ...
Espero que ajude!
 8
Author: Pedro Bezanilla, 2019-10-11 08:38:43

Mude o valor do seu fornecedor

beforeEach(() => {
   TestBed.configureTestingModule({
      declarations: [ UsersListComponent],
      providers: [{
         provide: TopToolBarService,
         useValue: jasmine.createSpyObj('TopToolBarService', ['getCustomer'])
      }],
      schemas:[CUSTOM_ELEMENTS_SCHEMA]
     });
     mockTopToolBarService = TestBed.get(TopToolBarService);

     mockTopToolBarService.getCustomer.and.returnValue(of([])); // mock output of function
   })

 2
Author: Islam Murtazaev, 2020-01-24 07:24:05

Tem de configurar o módulo de testes antes de executar o seu código. Ele não sabe sobre o seu objecto espião a menos que o passe para o TestBed.configureTestingModule como uma importação.

Https://angular.io/guide/testing#component-with-a-dependency

 0
Author: observingstream, 2019-10-10 21:33:09

Você pode considerar a utilização de ng-mocks para evitar todo o boilerplate para configurar TestBed.

beforeEach(() => MockBuilder(UsersListComponent)
  .mock(TopToolBarService, {
    // adding custom behavior to the service
    getCustomer: jasmine.createSpy().and.returnValue('king'),
  })
);

it('should return data from service function', () => {
  const fixture = MockRender(UsersListComponent);
  // now right after the render the property should be true
  expect(fixtur.point.componentInstance.bDefine).toBe(true);
}));
 0
Author: satanTime, 2020-12-21 07:34:48