简体   繁体   English

如何在单元测试之外模拟 Angular 服务?

[英]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.我正在开发一个 Angular 应用程序,因为后端在开发中仍然非常落后我正在构建替代假服务,它提供来自本地 JSON 文件的数据,允许我在本地工作站上测试应用程序的完整前端不依赖任何外部资源。

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.问题是每次我需要测试与后端的集成时从假服务切换到真实服务是浪费时间,所以我想要一些允许我在代码上使用简单标志在假服务和真实服务之间切换的东西或在 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.运行 angular 时,对 localhost:4200 的每个请求都可以重定向到具有相同路由的任何地方。 Either a node-express with fake jsons running in parallel or another mock server that you might have.具有并行运行的假 json 的 node-express 或您可能拥有的另一个模拟服务器。

https://angular.io/guide/build#proxying-to-a-backend-server 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 1-您可以使用像这样的节点模拟服务器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.节点模拟服务器将模拟后台 API,您只需为每个 http 查询提供 json 文件即可发送。 You can see at http://mock-server.com/ for more details.您可以在http://mock-server.com/上查看更多详细信息。

2- On your angular app, at the package.json file, add a new script which will start the mockserver and your application. 2- 在您的 angular 应用程序的 package.json 文件中,添加一个新脚本,该脚本将启动模拟服务器和您的应用程序。 Example: "mock:profile": "npm-run-all --parallel mockserver appmock"示例:“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. “appmock”脚本将使用像“proxy.mock.conf.json”这样的代理文件,它将所有 api 调用转发到 mockserver。

'mockserver' script is to run the mock server it self. 'mockserver' 脚本是运行它自己的模拟服务器。 It will be like "node./node/mock-server/mock.server.run.js"就像“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'要运行你的模拟模式,你只需要使用“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.我不确定您的服务是如何构建的,但如果您有一个抽象的“基础”http 服务,您可以检查一个标志并更改执行GET请求的 function 以获取本地 Z0ECD11C1D7A3BB7401D148A22 数据。

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:在您的服务中,您调用此“基础” http 服务的 get function :

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.这样,您只需切换一个 boolean 即可模拟您的所有服务。

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. PS我真的很喜欢将您的应用程序“代理”到模拟服务器的想法,我觉得这可能不是那么容易,但如果您希望从 JSON 更改数据,这是解决问题的更好方法。

You can add a MockInterceptor to your application, which alters the request url to the json-Path of your fake data.您可以将MockInterceptor添加到您的应用程序,这会将请求 url 更改为假数据的 json-Path。 You can add this interceptor dynamically using the production value from your environment.ts .您可以使用environment.ts中的production值动态添加此拦截器。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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