Angular 2 Integration Testing (Unit Test Style)

Is it possible to test an angular application with its testing base (primarily intended for unit testing) against a real backend?

Let's say E2E Testing with Protractor is not an option for me, but still I want to do some integration tests in my Unit Test environment with karma. It is really hard for me to find examples or even a statement if it is possible or not to use Jasmine and angular 2 test libraries.

I know that this should not be the best (or even good) practice, but that is not the topic here. Wherever I searched (and I searched a lot), I will find approaches with MockBackend and the statement "We do not want to hit the real backend ...", but it’s not said anywhere, if at all possible, and if so, how.

I tried several approaches (tests "normal" or asynchronous), spy on service methods from my Component test environment, calling the "Service" functions (which return an Observable after the backend is requested) and trying to continue the subscription functions from the inside, but my tests do not care. These parts are always skipped.

Imagine something like this:

 fit('should show an error if the email entered is invalid', async(() => { let accService: any = fixture.debugElement.injector.get(AccountService); let accSpy: jasmine.Spy = spyOn(accService, 'isExistingEmail').and.callThrough(); let checkEmailSpy: jasmine.Spy = spyOn(comp, 'checkEmail').and.callThrough(); expect(checkEmailSpy).not.toHaveBeenCalled(); emailInput.triggerEventHandler('blur', null); fixture.detectChanges(); expect(checkEmailSpy).toHaveBeenCalled(); expect(comp.emailInvalid).toBe(true); ... accService.isExistingEmail('abcdefg').subscribe((res) => { expect(accSpy).toHaveBeenCalledTimes(7); }, (err) => { expect(accSpy).toHaveBeenCalledTimes(7); }); accSpy.calls.mostRecent().returnValue.subscribe((res) => { expect(accSpy).toHaveBeenCalledTimes(7); }, (err) => { expect(accSpy).toHaveBeenCalledTimes(7); }); ... })); 

Now in the first part of this test, the blur event will call the component's checkEmail function, which will call something in my service (which will then ask another service for the actual backend call and return this observable). If the email is mistaken, false will be returned to the component function, and comp.emailInvalid - true).

The toHaveBeenCalled tests in this part actually pass, but the expect(comp.emailInvalid).toBe(true) does not work.

When I run the test and open the debug tab in Karma-Chrome-Launcher, I really see real server requests with the correct answer. So the queries are actually being executed, but I just don't return these answers to my test.

At the bottom of this example, I tried to use the service directly to get a response. So I tried to mock actual program flow to get backend responses. But in these cases, expect calls never run. However, if I put several console.log statements in the real service, I see that they are called twice (from the blur event and the direct call to accService.isExistingEmail ).

Any clues how I could handle this would be so appreciated.

The main reason for this is that we don’t want to set up huge layout files that mimic the reverse responses.

Edit:

If there is no solution for this, and I still do not want to use user interface tests like E2E with protractor, how could I do integration testing?

+5
source share

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


All Articles