Unit Testing: there is no provider for "InterceptableStoreFactory", even if it is added to the "providers",

I am working on unit tests in my Angular application, I am using the TestBed method,

I am testing components, so each specification file looks like this

import... describe('AppComponent', () => { // Importing dependecies beforeEach(async(() => { TestBed.configureTestingModule({ imports : [RouterTestingModule , HttpModule , FormsModule ], declarations: [AppComponent ], providers: [AUTH_PROVIDERS ,UserService, SharedclientService, RouteNavigator, JwtHelper, ReloadTokenService, ShopService , EnvVarsService, ProfileService, LocalStorageService, ApiVersionInterceptor, ApiTrackingInterceptor, MonitoringService , { provide: 'LOCAL_STORAGE_SERVICE_CONFIG', useValue: userConfig } , TokenUtilService , HttpInterceptorService , { provide: InterceptableStoreFactory, useClass: InterceptableStoreFactoryMock },ReloadTokenEventService , InterceptableStoreFactory ] }).compileComponents(); })); // detecting changes every times beforeEach(() => { fixture = TestBed.createComponent(AppComponent); component = fixture.componentInstance; fixture.detectChanges(); }); // Test case 0 (compilation of the component) it('AppComponent is well defined', () => { expect(component).toBeDefined(); }); // Test case 1 it('test', () => { expect("1").toBe("1"); }); }); 

This testing approach crashes the entire test suite if the dependency import is small.

For example : in this test suite, it raises this error:

No provider for InterceptableStoreFactory ! It seems strange since I import this service from my providers (last)

This leads to an almost complete failure of all test cases when checking the import of devices - these are β€œbefore each” test cases.

We are looking for the best ideas for:

  • "no service provider" problem (which has already been added to providers)

and for

  1. unit testBed is the best way to test
+5
source share
2 answers

You provide InterceptableStoreFactory twice. Once with a breadboard replacement and after the original. Try to remove one of them.

This can help you create a module for all of your services and put it in the "core" folder. (See Angular Style Guide )

This makes it easy to provide all the necessary services both in the test and in the development / production, without repeating yourself so much.

+3
source

1. No service provider

Remove the final InterceptableStoreFactory in the providers array. Since you already embed the InterceptableStoreFactory service layout earlier on the same line.

If this does not fix, please provide a fragment of your breadboard class InterceptableStoreFactoryMock and InterceptableStoreFactory .

2. Better Testing Strategy

For a better testing strategy, I would suggest a few things to make testing easier:

  • Offered here in Angular Styleguide: Collect all global services into one CoreModule . Then you can easily find out that all services are imported and easily import them for testing. I also recommend perhaps creating an explicit CoreTestingModule if you want to mock many of these services the same way for many components. Thus, saving reuse for all tests.
  • Offered here in Angular Styleguide: a SharedModule , in which you can export components, directives and channels that you reuse a lot in the application.
  • Consider using very small modules. In a FAQ at a conference in late 2017 or early 2018, Rob Wormald mentioned that each module in a Google Angular project has only 1.6 components. This means that each component test is much less likely to include services and other imports that it does not actually need. Thus, much less test refactoring is also required if you change the large module used by so many components. With smaller modules, your TestBed will also be much faster, as it will be much faster to reinitialize TestBed after each test case.
  • Consider moving more logic to services and channels, and first of all, switch the test focus to them. Since test services and channels can use the usual test infrastructure and, thus, skip the complexity of creating modules, because services and channels can be considered in the same way as ordinary classes and functions. As a note, I would mention that this is more or less automatically done by switching to the NGRX architecture .
  • This issue tracks a larger performance improvement for TestBed . The problem is that you have to recreate and break the module between each test case. To do this is much slower than just testing services, pipes, and other pure functions and classes. As mentioned earlier, this is slightly fixed using smaller modules. This issue also shows several hacks for using Jest or workarounds so that the modules do not need to be recreated for each test case and reused instead. The latter, however, modifies the private API, so it can easily disable your application between Angular patch releases, which is not a great place to post.
+1
source

Source: https://habr.com/ru/post/1273002/


All Articles