Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to combine a done callback with injection angular 2 unittest

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?

like image 437
Nikola Schou Avatar asked Feb 04 '17 23:02

Nikola Schou


People also ask

What is fixture detectChanges ()?

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.

What is beforeEach in Angular testing?

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.

What is SpyOn in Angular unit testing?

SpyOn is a Jasmine feature that allows dynamically intercepting the calls to a function and change its result.

What is Componentfixture in Angular testing?

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.


3 Answers

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);
    });
    
like image 74
Paul Samsotha Avatar answered Oct 13 '22 14:10

Paul Samsotha


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

like image 25
Pavel Agarkov Avatar answered Oct 13 '22 14:10

Pavel Agarkov


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

like image 42
rainerhahnekamp Avatar answered Oct 13 '22 14:10

rainerhahnekamp