I like the ability to pass in a done-callback when making unittest to explicitly control when a unittest is considered done. Can anyone explain how this can be combined with dependency injection when using Angular 2?
A little more background:
A normal unittest with a callback function looks like this:
it('should work with done', (done: Function) => {
setTimeout(() => {
a.test();
}, 1000);
a.test = () => {
console.log('zweiter test');
expect(true).toBeFalsy();
done();
};
A unittest generated by the angular 2 framework uses injection and looks like this:
it('should be defined', inject([TxparserService], (service: TxparserService) => {
expect(service).toBeTruthy();
}));
I want to use both a callback function and dependency injection. How does that look?
fixture is a wrapper for our component's environment so we can control things like change detection. To trigger change detection we call the function fixture.detectChanges() , now we can update our test spec to: Copy it('login button hidden when the user is authenticated', () => { expect(el. nativeElement.
beforeEach is a global function in Jasmine that runs some setup code before each spec in the test suite. In this test suite, beforeEach is used to create a testing module using the TestBed object and declares any components that would be used in this testing module.
SpyOn is a Jasmine feature that allows dynamically intercepting the calls to a function and change its result.
You can create a component fixture with TestBed. createComponent . Fixtures have access to a debugElement , which will give you access to the internals of the component fixture. Change detection isn't done automatically, so you'll call detectChanges on a fixture to tell Angular to run change detection.
Not sure if you can. Personally though, I stopped using this style of injection for a couple reasons: 1. It's pretty verbose, and 2. You need to keep repeating it for each test case. A couple other options are to:
Use a beforeEach
let service: TxparserService;
beforeEach(() => { // configure });
beforeEach(inject([TxperserverService], (svc: TxparserService) => {
service = svc;
}));
For me, the beforeEach
above, still breaks my first concern of being verbose, so I just do it this way now
let service: TxparserService;
beforeEach(() => {
TestBed.configureTestingModule({
providers: [ TxparserService ]
});
service = TestBed.get(TxparserService);
});
If you need to combine done
-style async test with injection you can simply do the following:
it('should work', (done) => inject([SomeService], (someService: SomeService) =>
{
expect(true).toEqual(true);
done();
})());
Make sure that you immediately call the function returned by inject
.
PS: Sometimes neither async
nor fakeAsync
works and you still need it to be done
in old-school fashion...
PPS: If someone is interested how to overcome problems with time-dependent operations of Observable with jasmine-marbles take a look at this short example: marble-scheduler-injector.ts
I was able to successfully combine fakeAsync with inject. So it would look like following:
it('should be defined', fakeAsync(inject([TxparserService], (service: TxparserService) => {
expect(service).toBeTruthy();
})));
You can combine it then with the tick()
function described in https://angular.io/guide/testing#the-fakeasync-function
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With