Reputation:
I want to test the data I receive from my service. I read angular documentation and I followed observable example but I don't receive any data when I subscribed to the observable. Console.log() isn't working inside the subscribe.
The service is working properly and get the right data in a real environment.
I tried to use async and doneFn but they didn't work both of them got time out.
Service File
export class BackService {
URL = '********'; // I removed url for security.
constructor(private httpClient: HttpClient) { }
getAllForms(): Observable<Array<object>> {
return this.httpClient.get<Array<object>>(`${this.URL}/allForms`);
}
getFormById(formId): Observable<Array<object>> {
return this.httpClient.get<Array<object>>(`${this.URL}/form/${formId}`);
}
}
Test Service File
import { TestBed } from '@angular/core/testing';
import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
import { BackService } from './back.service';
describe('BackService', () => {
let httpMock: HttpTestingController;
let backService: BackService;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [ HttpClientTestingModule ],
providers: [BackService]
});
backService = TestBed.get(BackService);
httpMock = TestBed.get(HttpTestingController);
});
it('should be created', () => {
expect(backService).toBeTruthy();
});
describe('Methods', () => {
describe('All Forms', () => {
it('should use GET method', () => {
backService.getAllForms().subscribe();
const req = httpMock.expectOne(`${backService.URL}/allForms`);
expect(req.request.method).toBe('GET');
});
it('should use the right url', () => {
backService.getAllForms().subscribe();
const req = httpMock.expectOne(`${backService.URL}/allForms`);
expect(req.request.url).toBe(`${backService.URL}/allForms`);
});
it('should return the right data', () => {
const mockData = [{'_id': 435345345, '_type': 'window'}]
backService.getAllForms().subscribe(data => {
expect(data).toEqual(mockData);
});
});
});
});
Upvotes: 1
Views: 2605
Reputation: 205
Can you try with MockBackend instead?
import { TestBed, inject } from "@angular/core/testing";
import {
HttpModule,
Http,
Response,
ResponseOptions,
XHRBackend
} from "@angular/http";
import { MockBackend } from "@angular/http/testing";
import { BackService } from "./back.service";
describe("BackService", () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [HttpModule],
providers: [BackService, { provide: XHRBackend, useClass: MockBackend }]
});
});
describe("getAllForms()", () => {
it("should return an Observable<Array<Form>>", inject(
[BackService, XHRBackend],
(backService, mockBackend) => {
const mockResponse = {
data: [
{ id: 0, form: "Form 0" },
{ id: 1, form: "Form 1" },
{ id: 2, form: "Form 2" },
{ id: 3, form: "Form 3" }
]
};
mockBackend.connections.subscribe(connection => {
connection.mockRespond(
new Response(
new ResponseOptions({
body: JSON.stringify(mockResponse)
})
)
);
});
backService.getAllForms().subscribe(forms => {
expect(forms.length).toBe(4);
expect(forms[0].form).toEqual("Form 0");
expect(forms[1].form).toEqual("Form 1");
expect(forms[2].form).toEqual("Form 2");
expect(forms[3].form).toEqual("Form 3");
});
}
));
});
});
Upvotes: 0
Reputation: 16
First 2 tests look ok, for third test to receive data that you can test on, you have to trigger that "httpMock" by calling its flush() method with necessary object you want your httpClient to return.
This should work for third test:
it('should return the right data', () => {
const mockData = [{'_id': 435345345, '_type': 'window'}]
backService.getAllForms().subscribe(data => {
expect(data).toEqual(mockData);
});
const req = httpMock.expectOne(`${backService.URL}/allForms`);
req.flush(mockData);
});
Upvotes: 0
Reputation: 43
we do pact tests because you have to mock a lot which didn't feel real for us.
Example
import {PactWeb} from '@pact-foundation/pact-web';
describe('FooService', () => {
let provider: PactWeb;
beforeAll(async () => {
await provider.addInteraction({
state: 'I have an foo',
uponReceiving: 'a request to create an bar',
withRequest: {
method: 'POST',
path: '/url/bars',
body: {
foo: '123456',
bar: 'abcd'
}
},
willRespondWith: {
status: 200,
headers: {'Content-Type': 'application/json'},
body: {
foo: '123456',
bar: 'abcd'
}
}
});
});
it('should create one bar and respond with that bar', async () => {
const service: FooService = TestBed.get(FooService);
(service as any).apiBasePath = provider.mockService.baseUrl + 'url';
const result = await service.createBar({
foo: '123456',
bar: 'abcd'
}).toPromise();
expect(result.id).toEqual('some-random-uuid');
});
afterAll(function (done) {
provider.finalize()
.then(function () {
done();
}, function (err) {
done.fail(err);
});
});
});
I assume, that you have a service called "createBar" that you want to test.
State Is just to know what you are doing, so it is the state of the provider. He has a foo. And uponReceiving of the request he should create a bar
withRequest Shows how the request should look like
willRespondWith Shows the response.
Upvotes: 0