What is the easiest way to mock the response returned by Http
get()
in Angular 2?
I have local data.json
file in my working directory, and I want get()
to return response containing that data as a payload, simulating the rest api.
Documents for configuring the Backend
object for Http
seemed somewhat obscure and overplicated for such a simple task.
What is the easiest way to mock the response returned by Http
get()
in Angular 2?
I have local data.json
file in my working directory, and I want get()
to return response containing that data as a payload, simulating the rest api.
Documents for configuring the Backend
object for Http
seemed somewhat obscure and overplicated for such a simple task.
-
No idea why you think configuring
Backend
is obscure. DI is a major and basic building block of Angular2 and this is exactly the use case DI is made for. What's plicated withMockBackend, provide(XHRBackend, {useExisting: MockBackend})
. It's simple and straight-forward. – Günter Zöchbauer Commented May 30, 2016 at 13:19 - @GünterZöchbauer Software engineers es in a variety. Just because something is easy for the top 50 percentile, doesn't make it easy for the bottom 50. It's never good to be so dismissive of another person's POV without actually being in their shoes. – Ka Mok Commented Jan 18, 2017 at 18:18
- 1 @KaMok My ment isn't dismissive. If someone wants a solution, he needs to provide information about what the problem is. That was my ment about. "Documents for configuring the Backend object for Http seemed somewhat obscure and overplicated for such a simple task." is just useless ranting. If he had provided a link or posted the code he found overplicated there had been something to discuss about, but the way it is, it's not really a question. I just tried to get more information. – Günter Zöchbauer Commented Jan 18, 2017 at 18:27
3 Answers
Reset to default 2You need to override the XhrBackend
provider with the MockBackend
one. You need then to create another injector to be able to execute a true HTTP request.
Here is a sample:
beforeEachProviders(() => {
return [
HTTP_PROVIDERS,
provide(XHRBackend, { useClass: MockBackend }),
SomeHttpService
];
});
it('Should something', inject([XHRBackend, SomeHttpService], (mockBackend, httpService) => {
mockBackend.connections.subscribe(
(connection: MockConnection) => {
var injector = ReflectiveInjector.resolveAndCreate([
HTTP_PROVIDERS
]);
var http = injector.get(Http);
http.get('data.json').map(res => res.json()).subscribe(data) => {
connection.mockRespond(new Response(
new ResponseOptions({
body: data
})));
});
});
}));
By the way, you need to mock the XHRBackend
and provide mocked data in a class with the createDb
method. createDb
method returns the mocked JSON object. To load that data provide correct URL
to http.get
, for example, if JSON object is contained in a variable mockedObject
, then the URL should be "app\mockedObject"
.
You can read more details here: https://angular.io/docs/ts/latest/guide/server-munication.html.
You can use the HttpTestingController available via the core TestBed as to me it feels more intuitive (each to their own, of course). Untested snippet:
import { TestBed, async } from '@angular/core/testing';
import { HttpTestingController } from '@angular/mon/http/testing';
import { MyApiService } from './my-api.service';
export function main() {
describe('Test set', () => {
let httpMock: HttpTestingController;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [],
providers: [MyApiService]
});
httpMock = TestBed.get(HttpTestingController);
});
it('should call get', async(() => {
const data: any = {mydata: 'test'};
let actualResponse: any = null;
MyApiService.get().subscribe((response: any) => {
actualResponse = response;
});
httpMock.expectOne('localhost:5555/my-path').flush(data);
expect(actualResponse).toEqual(data);
}));
});
}