Javascript Angular 4-如何为原型设计和开发模拟数据

Javascript Angular 4-如何为原型设计和开发模拟数据,javascript,angular,unit-testing,Javascript,Angular,Unit Testing,我正在将AngularJSV1.5项目升级到Angular4.x。在开发原始AngularJS应用程序的过程中,我们将使用ngMocks包来模拟实际的web服务API响应,并在页面上相应地显示数据。这在开发过程中非常有用,因为我不必为以后的删除硬编码值。最重要的是,我们将Webpack配置为在开发期间仅包含模拟数据,并在构建应用程序以供生产使用时忽略这些模拟数据文件。模拟数据的配置如下: /* app-login.mock.js */ import angular from 'angular';

我正在将AngularJSV1.5项目升级到Angular4.x。在开发原始AngularJS应用程序的过程中,我们将使用
ngMocks
包来模拟实际的web服务API响应,并在页面上相应地显示数据。这在开发过程中非常有用,因为我不必为以后的删除硬编码值。最重要的是,我们将Webpack配置为在开发期间仅包含模拟数据,并在构建应用程序以供生产使用时忽略这些模拟数据文件。模拟数据的配置如下:

/* app-login.mock.js */
import angular from 'angular';
import 'angular-mocks';

angular.module('app').run(function ($httpBackend) {
    $httpBackend
        .whenPOST('./api/auth')
        .respond(function(method, url, data) {
            var credentials = angular.fromJson(data);
            if (credentials.username == 'gooduser') {
                return [200, {'token': createToken(credentials.username)}];
            } else {
                return [401, {'errorMsg': 'Mock login only allows username "gooduser"'}];
            }
        });
});

function createToken(username) {
    // Create a token, which is valid enough for testing purposes.
    // This token is based on the actual token generated by the web service.
    let currentTime = new Date();
    let futureTime = new Date(currentTime.getTime() + ((currentTime.getHours() + 8) * 60 * 60 * 1000));

    let header = {
        alg: 'HS512'
    };

    let payload = {
        exp: futureTime.getTime() / 1000,
        sub: username,
        roles: 'SOME_APPLICATION_ROLES',
        iat: currentTime.getTime() / 1000
    };

    return `${btoa(angular.toJson(header))}.${btoa(angular.toJson(payload))}`;
}
import { InMemoryDbService } from 'angular-in-memory-web-api';

import { IProduct } from './product';

export class ProductData implements InMemoryDbService {

    createDb() {
        let products: IProduct[] = [
            {
                'id': 1,
                'productName': 'Leaf Rake',
                'productCode': 'GDN-0011',
                'releaseDate': 'March 19, 2016',
                'description': 'Leaf rake with 48-inch wooden handle.',
                'price': 19.95,
                'starRating': 3.2,
                'imageUrl': 'http://openclipart.org/image/300px/svg_to_png/26215/Anonymous_Leaf_Rake.png',
                'tags': ['rake', 'leaf', 'yard', 'home']
            }, 
            // ...
        ];
        return { products };
    }
}
然后将Webpack配置为将所有“模拟”文件包含到构建包中,然后可以将其显示为真实的HTTP响应

/* webpack.config.js */
const isProd = process.env.NODE_ENV === 'production';

const entry = {
    app: (() => {
        let app = [
            'babel-polyfill',
            path.join(PATHS.app, 'pollyfills.ts'),
            path.join(PATHS.app, 'main.ts')
        ];

        if (isProd) {
            app.push(path.join(PATHS.app, 'app.prod.js'));
        } else {
            app.push(path.join(PATHS.app, 'app.mock.js'));
        }

        return app;
    })()
};

module.exports = {
    entry,
    // ...other exports
};
然后是
app.mock.js
文件:

/* app.mock.js */
var mockContext = require.context(".", true, /\.mock$/);
mockContext.keys().forEach(mockContext);
我在互联网上搜索,寻找一种与我们以前的解决方案一样有效的解决方案,尽管我还没有找到任何好的答案。我发现最好的是关于如何设置返回模拟数据的单元测试的教程,虽然这对测试功能很有用,但它不能帮助我在开发过程中测试应用程序


我还看到了一些关于使用Angular 4中新的
HttpClient
类设置
拦截器的文档,但我不确定如何在仅允许在开发期间将其添加到我们的网页包配置中。有人对该怎么做有什么建议吗?

我使用angular in-memory web api。你可以在这里找到它:

更新:回购被移动到此处,在角度/角度回购中:

它拦截所有http调用,并处理您提供的示例数据

要从开发更改为生产,需要删除导入。或者,您也可以编写两个不同的模块,一个使用开发导入,另一个使用生产导入,并包括一个或另一个与您现在所做的类似的webpack。(但我还没有试过这个。)

您可以这样设置数据:

/* app-login.mock.js */
import angular from 'angular';
import 'angular-mocks';

angular.module('app').run(function ($httpBackend) {
    $httpBackend
        .whenPOST('./api/auth')
        .respond(function(method, url, data) {
            var credentials = angular.fromJson(data);
            if (credentials.username == 'gooduser') {
                return [200, {'token': createToken(credentials.username)}];
            } else {
                return [401, {'errorMsg': 'Mock login only allows username "gooduser"'}];
            }
        });
});

function createToken(username) {
    // Create a token, which is valid enough for testing purposes.
    // This token is based on the actual token generated by the web service.
    let currentTime = new Date();
    let futureTime = new Date(currentTime.getTime() + ((currentTime.getHours() + 8) * 60 * 60 * 1000));

    let header = {
        alg: 'HS512'
    };

    let payload = {
        exp: futureTime.getTime() / 1000,
        sub: username,
        roles: 'SOME_APPLICATION_ROLES',
        iat: currentTime.getTime() / 1000
    };

    return `${btoa(angular.toJson(header))}.${btoa(angular.toJson(payload))}`;
}
import { InMemoryDbService } from 'angular-in-memory-web-api';

import { IProduct } from './product';

export class ProductData implements InMemoryDbService {

    createDb() {
        let products: IProduct[] = [
            {
                'id': 1,
                'productName': 'Leaf Rake',
                'productCode': 'GDN-0011',
                'releaseDate': 'March 19, 2016',
                'description': 'Leaf rake with 48-inch wooden handle.',
                'price': 19.95,
                'starRating': 3.2,
                'imageUrl': 'http://openclipart.org/image/300px/svg_to_png/26215/Anonymous_Leaf_Rake.png',
                'tags': ['rake', 'leaf', 'yard', 'home']
            }, 
            // ...
        ];
        return { products };
    }
}
您可以使用普通的Http或HttpClient构建数据访问服务


我这里有一个关于所有CRUD操作的完整示例:

您是否尝试过json服务器。我在我们的应用程序中使用了它,我从未听说过,但我会亲自看看。谢谢你的建议!Angular in-memory web api github repo已由所有者存档,所有者有一个限制,即该库不稳定,如果打破它,他们不会感觉不好:“最重要的是,它始终是实验性的。我们将进行突破性的更改,我们不会感觉不好,因为这是一个开发工具,而不是生产产品。”你仍然建议使用它吗?它被归档的原因是因为它被移到了angular/angular github repo中:是的,我仍然建议它在开发过程中模拟CRUD操作。