Reputation: 2212
testing a component that needs to subscribe to a service, but the jasmine test always fails
I log the service to the console and use expect(contactService).toBeDefined()
which returns success
But as soon as I subscribe it returns undefined
spec:
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { ContactComponent } from './contact.component';
import { DivPositionsService } from '../../../services/div-positions.service';
import { ContactService } from '../../../services/contact.service';
import { HttpClientModule } from '@angular/common/http';
import { NO_ERRORS_SCHEMA } from '@angular/core';
import { Email } from '../../../models/email.model';
import { HttpClientTestingModule, HttpTestingController } from '../../../../../node_modules/@angular/common/http/testing';
describe('ContactComponent', () => {
let component: ContactComponent;
let fixture: ComponentFixture<ContactComponent>;
let contactService;
let httpMock: HttpTestingController;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ ContactComponent ],
imports:[
FormsModule,
ReactiveFormsModule,
HttpClientModule, HttpClientTestingModule],
providers:[
{
provide: ContactService,
useValue: jasmine.createSpyObj('contactService', ['sendMail'])
},
{
provide: DivPositionsService,
useValue: jasmine.createSpyObj('divPositionsService', ['updateObj'])
}],
schemas: [NO_ERRORS_SCHEMA]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(ContactComponent);
component = fixture.componentInstance;
contactService = TestBed.get(ContactService);
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
it('should create form ngOnInit', () => {
component.ngOnInit()
expect(component.contactForm).toBeDefined();
});
it('should submit values from form', () => {
const successMsg = {sucess: true, msg: 'sent'}
const contact:Email = {
name:'Test name',
email: 'Test email',
message: 'Test message',
phone: 'Test phone'
}
console.log(contactService)
expect(contactService).toBeDefined()
contactService.sendMail(contact)
.subscribe(results => {
// expect(results).toBeDefined();
//has to be what is returned by the function
console.log(results)
expect(results).toEqual(successMsg);
});
console.log(contactService)
});
});
Upvotes: 2
Views: 6018
Reputation: 527
First, you spy on the contactService
, which following the code you provide, not be defined in anywhere.
And you should define your contactSevice
before the compileComponents()
function being executed.
so you should doing something like this.
TestBed.configureTestingModule({
declarations: [ ContactComponent ],
imports:[
FormsModule,
ReactiveFormsModule,
HttpClientModule, HttpClientTestingModule],
providers:[
...,
{
provide: ContactService,
useValue: class {
sendMail: () => of({//what ever object you want to return here});
}
}],
schemas: [NO_ERRORS_SCHEMA]
})
.compileComponents();
But the approach above make your mock service function called and you can't actually spy on it
If you need to spy on that and do whatever you want with mock service
You could implement a mock class like this:
class MockContactService {
sendMail() {
return of({});
}
}
let mockContactService;
beforeEach(()=> {
mockContactService = new MockContactService();
TestBed.configureTestingModule({
...,
providers:[
{
provide: ContactService,
useValue: mockContactService,
}],...
})
.compileComponents();
it('what ever', () => {
spyOn(mockContactService, 'sendMail');
})
})
Upvotes: 1
Reputation: 7803
Before your call to contactService.sendMail(contact),
you should mock the return value of sendMail
, something like this.
contactService.sendMail.and.returnValue(Observable.of(successMsg));
Hope it helps
Upvotes: 2