Search code examples
angularunit-testing

How to test Angular frontend without backend


Deploying project Backend is not possible right now, because it not ready, but I need develop and test Angular Frontend step-by-step.
I know any Json response from my Backend, also I know that Angular has a lot of various inMemory Database, for example Apollo. But how exactly I can do this?

First step is testing login page, this is ordinary page with request to server Email/Password and return JWT, so I need something integrate to my project JWT generator based on Email/Password and something redirect login request to this JWT generator.

Next step - my project has standard AuthInterceptor based on AuthService

var token = this.authService.getToken(); 
if (token) {
  req = req.clone({
    setHeaders: {
      Authorization: `Bearer ${token}`
    }
  });
} 

where

  getToken(): string | null {
     return localStorage.getItem(this.tokenKey);
  }

And main third step, how to load to something database (Apollo or ?) Json response from my Backend and redirect Get/Post request from real Backend endpoint to my Backend emulator service what will inject API result from JS DB.

This is absolutely standard and must have step for any Fronend development workflow, but unfortunately I can not found full and clear instruction about this.


Solution

  • Cypress can help you. It's a Test Framework to test any things on the Frontend. But for this your Frontend need to be finsihed; Tests are only relevant for test a expect behavior; But you can "fake" some requests they come from backend.

    Here is a short example hot to intercept a request with cypress

    describe('Example to demonstrate API Mocking in Cypress using cy.intercept', () => {
    
        beforeEach(() => {
            cy.intercept('GET', '**/tags', { fixture: 'tags.json' })
            cy.intercept('GET', '**/articles*', { fixture: 'articlefeed.json' })
            cy.visit('https://angular.realworld.io/')
        })
    
        it('Mock the Tags from the API Response and then validate on UI', () => {
            cy.get('.tag-list', { timeout: 10000 })
                .should('contain', 'cypress')
                .and('contain', 'selenium')
        })
    
        it('Mock the Article feed from the API Response and then validate on UI', () => {
            cy.get('app-favorite-button.pull-xs-right').contains('10')
            cy.get('.author').contains('testersdock')
            cy.get('.preview-link > p').contains('This is a test description')
        })
    })
    

    Read the complete article here.

    But my opinion to you: If you're putting so much energy into a "fake backend", it probably makes more sense to finish the real backend.

    Write one simple file which includes some JSON or JS objects. And then return this from your Service from Angular. You can use Observables with delays to fake loading scenarios.

    const myArray = [ { token: "eqKe93l....", user: "Test" } ];
     
    // enable loading=true;
    
    from(myArray).pipe(
            concatMap( item => of(item).pipe ( delay( 1000 ) ))
        ).subscribe ( timedItem => {
            // disable loading=false;
            console.log(timedItem)
        });
    

    And again: Fake data is the way to build a Frontend first. But put not too much energy into it and do not create a extra database and so on. Do it as simple as possible!