slipperypete
slipperypete

Reputation: 6246

How to mock a service in a test file that is being called in OnInit of the component being tested?

In AutoReceptionistRecommendation.component.ts

I have an ngOninit method that looks like this:

  ngOnInit() {
    this.city = this.employee.getEmpData().city;
  }

In the test file AutoReceptionistRecommendation.component.spec.ts

I have code that looks like this:

describe('AutoReceptionistRecommendationComponent', () => {
  let component: AutoReceptionistRecommendationComponent;
  let fixture: ComponentFixture<AutoReceptionistRecommendationComponent>;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [ AutoReceptionistRecommendationComponent ],
      imports: [
        FormsModule,
        MatCardModule,
        MatIconModule,
        HttpModule
      ],
      providers: [
        EmployeeService,
        EmployeeHttpService
      ]
    })
    .compileComponents();
  }));

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

  it('should be created', () => {
    expect(component).toBeTruthy();
  });
});

When I run ng test I get an error that looks like this:

Uncaught NetworkError: Failed to execute 'send' on 'XMLHttpRequest': Failed to load 'ng:///DynamicTestModule/AutoReceptionistRecommendationComponent_Host.ngfactory.js'.

If I remove the line in NgOnInit this error does not occur, and the test continues. I think that I have to mock this service somehow in order for the test to go through. What is the best way to do that, can somebody provide documentation that explains how to do this? Or give me insight as to why this error occurs with the line in ngOninit and does not occur when it is not there?

Upvotes: 1

Views: 2123

Answers (1)

Estus Flask
Estus Flask

Reputation: 222484

Efficient unit testing requires to isolate currently tested unit from other moving parts.

Real HttpModule shouldn't be used in unit tests. The requests should be mocked with MockBackend when testing the units that use Http directly. Otherwise these units should be mocked, like:

providers: [
  ...
  { provide: EmployeeService, useValue: jasmine.createSpyObj('', ['getEmpData']) }
]

Component ngOnInit is called on first detectChanges call. This means that employee.getEmpData should be mocked beforehand:

component = fixture.componentInstance;
employee.getEmpData.and.returnValue({ city: ... });
fixture.detectChanges();

Upvotes: 2

Related Questions