How override Provider in Angular 5 for only one test?

半世苍凉 提交于 2019-12-22 03:51:32

问题


In one of my unit test files, I have to mock several times the same service with different mocks.

import { MyService } from '../services/myservice.service';
import { MockMyService1 } from '../mocks/mockmyservice1';
import { MockMyService2 } from '../mocks/mockmyservice2';
describe('MyComponent', () => {

    beforeEach(async(() => {
        TestBed.configureTestingModule({
        declarations: [
            MyComponent
        ],
        providers: [
            { provide: MyService, useClass: MockMyService1 }
        ]
        })
        .compileComponents();
    }));

    beforeEach(() => {
        fixture = TestBed.createComponent(MapComponent);
        mapComponent = fixture.componentInstance;
        fixture.detectChanges();
    });

    describe('MyFirstTest', () => {
        it('should test with my first mock', () => {
            /**
             * Test with my first mock
             */
        });
    });

    describe('MySecondTest', () => {
        // Here I would like to change { provide: MyService, useClass: MockMyService1 } to { provide: MyService, useClass: MockMyService2 }

        it('should test with my second mock', () => {
            /**
             * Test with my second mock
             */
        });
    });
});

I see that the function overrideProvider exists, but I did not manage to use it in my test. When I use it in a "it", the provider doesn't change. I didn't manage to find an example where this function is called. Could you explain me how to use it properly? Or have you an other method to do that?


回答1:


If the service is injected as public property, e.g.:

@Component(...)
class MyComponent {
  constructor(public myService: MyService)
}

You can do something like:

it('...', () => {
  component.myService = new MockMyService2(...); // Make sure to provide MockMyService2 dependencies in constructor, if it has any.
  fixture.detectChanges();

  // Your test here...
})

If injected service is stored in a private property, you can write it as (component as any).myServiceMockMyService2 = new MockMyService2(...); to bypass TS.

It's not pretty but it works.

As for TestBed.overrideProvider, I had no luck with that approach (which would be much nicer if it worked):

it('...', () =>{
  TestBed.overrideProvider(MyService, { useClass: MockMyService2 });
  TestBed.compileComponents();
  fixture = TestBed.createComponent(ConfirmationModalComponent);
  component = fixture.componentInstance;
  fixture.detectChanges();

  // This was still using the original service, not sure what is wrong here.
});



回答2:


As of angular 6 I noticed that overrideProvider works with the useValue property. So in order to make it work try something like:

class MockRequestService1 {
  ...
}

class MockRequestService2 {
  ...
}

then write you TestBed like:

// example with injected service
TestBed.configureTestingModule({
  // Provide the service-under-test
  providers: [
    SomeService, {
      provide: SomeInjectedService, useValue: {}
    }
  ]
});

And whenever you want to override the provider just use:

TestBed.overrideProvider(SomeInjectedService, {useValue: new MockRequestService1()});
// Inject both the service-to-test and its (spy) dependency
someService = TestBed.get(SomeService);
someInjectedService = TestBed.get(SomeInjectedService);

Either in a beforeEach() function or place it in an it() function.




回答3:


Just for reference, if annynone meets this issue.

I tried to use

TestBed.overrideProvider(MockedService, {useValue: { foo: () => {} } });

it was not working, still the original service was injected in test (that with providedIn: root)

In test I used alias to import OtherService:

import { OtherService } from '@core/OtherService'`

while in the service itself I had import with relative path:

import { OtherService } from '../../../OtherService'

After correcting it so both test and service itself had same imports TestBed.overrideProvider() started to take effect.

Env: Angular 7 library - not application and jest



来源:https://stackoverflow.com/questions/48811091/how-override-provider-in-angular-5-for-only-one-test

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!