简体   繁体   中英

How to mock Angular service outside unit testing?

I'm developing an Angular application, since the back-end is still very behind in the development I'm building alternative fake services which provides data from local JSON files allowing me to test the full front-end of the application on my local workstation without relying on any external resource.

The problem is that switching from fake services to real services every time I need to test the integration with the back-end is a waste of time so I wanted something which allows me to switch between fake and real services with a simple flag on the code or on the CLI.

You can use the proxy for that. When running angular every request for localhost:4200 can be redirected to any place with the same route. Either a node-express with fake jsons running in parallel or another mock server that you might have.

https://angular.io/guide/build#proxying-to-a-backend-server

Better to use an independent mockserver. So your app will be cleaner and easier to test

1- You can use a node mock server like this one https://www.npmjs.com/package/mockserver-node

the node mock server will simulate the back apis, you will only have to give it the json file to send for each http query. You can see at http://mock-server.com/ for more details.

2- On your angular app, at the package.json file, add a new script which will start the mockserver and your application. Example: "mock:profile": "npm-run-all --parallel mockserver appmock"

'appmock' script will use a proxy file like 'proxy.mock.conf.json' which will forward all api calls to mockserver.

'mockserver' script is to run the mock server it self. It will be like "node./node/mock-server/mock.server.run.js"

To run you mock mode, you will have to only run you app with 'npm run mock:profile'

I'm not sure how your services are built but if you have an abstract "base" http service, you can check for a flag and change the function that do the GET request to fetch local JSON data.

something like:

export class baseHttpService {
    let isMock: boolean = true;

    get(url: string, params: object = {}): Observable<any> { 
        if(!isMock) {
            return /* normal get function */
        } else {
            return this.http.get("your local json file");
        }
    }
}

And in your Service, you call the get function of this "base" http service:

export class UserService {

    getUser() Observable<any>{
        this.baseHttp.get(/* Api endpoint to get user */).subscribe(...);
    }
}

This way, you only need to toggle one boolean to mock all of your service.

PS I really like the idea of "Proxying" your app to a mock server, i feel like it's might not be as easy but it's a better way to approach the problem if you wish to change your data from your JSON.

You can add a MockInterceptor to your application, which alters the request url to the json-Path of your fake data. You can add this interceptor dynamically using the production value from your environment.ts .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM