我正在将AngularJS v1.5项目升级到Angular 4.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))}`;
}
然后将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中的新Interceptors
类设置HttpClient
的文档,但是我不知道如何在仅仅条件下将它添加到我们的Webpack配置中在开发过程中被允许。有没有人对如何做有任何建议?
答案 0 :(得分:4)
我使用angular-in-memory-web-api。您可以在此处找到它:https://github.com/angular/in-memory-web-api
它会截取您的所有http调用,并使用您提供的示例数据。
要从开发更改为生产,您需要删除导入。或者您可以编写两个不同的模块,一个使用dev导入,另一个使用生产导入,并使用类似于现在的webpack包含一个或另一个。 (但我没试过这个。)
您可以像这样设置数据:
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操作的完整示例:https://github.com/DeborahK/Angular2-ReactiveForms