Reputation: 125
Im new to whole unit testing scene with Angular, so would be great if guys could point me in the direction.. Im trying to create a fake service and pass back data to which i can run a few simple test..
When I go to run the test it seems to fail with
Server error at webpack:///~/rxjs/Subscriber.js:194:0 <- config/karma-test-shim.js:20301
I don't think it my webpack config.. Here is my code anway...
import { SearchModule } from './search.module';
import { SearchService } from './search.services';
import { HttpModule } from '@angular/http';
import { inject, TestBed } from '@angular/core/testing';
import { Observable } from 'rxjs/Observable';
import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing';
class SearchServiceMock {
search() {
return Observable.of(
[
{
"title": "title_1",
"artist": "artist_1",
"release": "06/02/2016",
"slug": "slug-1"
},
{
"title": "title_2",
"artist": "artist_1",
"release": " 27/01/2017",
"slug": "slug-2"
},
{
"title": "title_3",
"artist": "artist_3",
"release": "17/02/2017",
"slug": "slug-3"
}
]
)
}
}
describe('Service: TracksServices', () => {
let searchService: SearchService;
beforeEach(() => TestBed.configureTestingModule({
imports: [ SearchModule, HttpModule ],
providers: [
{ provide: SearchService, useClass: SearchServiceMock },
]
}));
beforeEach(inject([SearchService], (s: any) => {
searchService = s;
}));
it('Search results 3', () => {
searchService.search('track 1', 1, 4).subscribe(
(x:any) => {
// expect(x).toContain(track);
expect(x.length).toEqual(3);
}
);
});
});
The test still seems to be getting the real service i think when I want to use a fake one
Upvotes: 1
Views: 1301
Reputation: 8948
I know the pain of getting into Unit testing, in JavaScript, and in Angular, and it took me a few tries to wrap my head around it.
So I hope the following explanation will help sort out the confusion:
The object you are testing is called "Object under test"
In your case it is the SearchService
.
A Mock is one type of fake objects.
These fake objects have lots of various names and purposes - Mocks, Spies, stubs, etc..
But the general name coined by Gerard Meszaros and explained here is Test Doubles.
The object under test often has dependencies on other objects. These dependencies are also called collaborators
Replacing your object's collaborators with test doubles is done for the purpose of testing how the Object interacts with them.
The idea is to "record" that interaction, and it is done with spies (in Jasmine - jasmine.createSpy()
).
One way of testing http calls -
You're not obligated to use TestBed
for testing a service, it is more useful for testing reusable components, because of its DOM capabilites.
You can create a fake object which has the same methods like Angular's Http objects, but replaced with spies.
Then create a new SearchService(httpSpy)
instance.
This will give you a copy of your service, which you can test.
Then call methods on that the REAL service under test and investigate the relevant spy for the result.
Another way to test http calls
You can use the MockBackend
class and configure the Http service to use a fake backend instead, like in this doc
It's hard to say without seeing a plunker of the example with the real service under test code.
If you're new to testing, you can learn more about Test Doubles and how unit testing is done in my (free) theory course about JavaScript Unit Testing and TDD
Hope it helps.
Upvotes: 4