我们只是在一个真实的服务上运行了我们的应用程序,但是为了开发和测试我们的应用程序,我们不想依赖于“真实”服务的可用性,也不想给数据服务所在的系统增加额外的负载。
文件结构
在这一步之后,我们的应用程序项目的文件夹结构很清楚地将测试文件和生产文件分开。新的测试文件夹现在包含一个新的HTML页面mockServer.html,它将在测试模式下启动我们的应用程序,而不需要调用真正的服务。
新的localService文件夹包含OData的元数据.xml服务描述文件,mockserver.js使用本地数据模拟真实的服务,以及mockdata子文件夹,该文件夹包含本地测试数据(invoics .json)。
webapp/test/mockServer.html (New)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>SAPUI5 Walkthrough</title>
<script
id="sap-ui-bootstrap"
src="https://openui5.hana.ondemand.com/resources/sap-ui-core.js"
data-sap-ui-theme="sap_belize"
data-sap-ui-libs="sap.m"
data-sap-ui-resourceroots='{
"sap.ui.demo.walkthrough": "./"
}'
data-sap-ui-oninit="module:sap/ui/core/ComponentSupport"
data-sap-ui-compatVersion="edge"
data-sap-ui-async="true">
</script>
</head>
<body class="sapUiBody" id="content">
<div data-sap-ui-component data-name="sap.ui.demo.walkthrough" data-id="container" data-settings='{"id" : "walkthrough"}'></div>
</body>
</html>
我们将index.html复制到webapp/test文件夹中的一个单独的文件中,并将其命名为mockServer.html。现在,我们将使用这个文件在测试模式下运行应用程序,并从JSON文件中加载模拟数据。测试页不应该放在应用程序根文件夹中,而应该放在名为Test的子文件夹中,以清楚地将生产代码和测试代码分开。
从这一点开始,您就有了两个不同的输入页面:一个用于真正的“连接”应用程序(index.html),另一个用于本地测试
(mockServer.html)。您可以自由决定下一步是在真正的服务数据上还是在应用程序内的本地数据上执行。
如果真实的服务连接不可用,或者上一步中的代理配置不起作用,就需要使用mockServer.html文件。这将显示具有模拟测试数据的应用程序。html文件总是从远程服务器加载数据。如果请求失败,发票列表将保持空。
webapp/test/mockServer.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
**<meta name="viewport" content="width=device-width, initial-scale=1.0">**
<title>SAPUI5 Walkthrough - Test Page</title>
<script
id="sap-ui-bootstrap"
src="https://openui5.hana.ondemand.com/resources/sap-ui-core.js"
data-sap-ui-theme="sap_belize"
data-sap-ui-resourceroots='{
**"sap.ui.demo.walkthrough": "../"**
}'
**data-sap-ui-oninit="module:sap/ui/demo/walkthrough/test/initMockServer"**
data-sap-ui-compatVersion="edge"
data-sap-ui-async="true">
</script>
</head>
<body class="sapUiBody" id="content">
<div data-sap-ui-component data-name="sap.ui.demo.walkthrough" data-id="container" data-settings='{"id" : "walkthrough"}'></div>
</body>
</html>
我们修改了mockServer.html文件并更改了页面标题,以将其与生产的开始页面区分开来。在引导程序中,data-sap-ui-resourceroots属性也被更改了。名称空间现在指向上面的文件夹(" …/ "),因为mockServer.html文件现在位于webapp文件夹的子文件夹中。我们现在调用脚本initMockServer.js,而不是直接加载应用组件。
webapp/test/initMockServer.js (New)
sap.ui.define([
"../localService/mockserver"
], function (mockserver) {
"use strict";
// initialize the mock server
mockserver.init();
// initialize the embedded component on the HTML page
sap.ui.require(["sap/ui/core/ComponentSupport"]);
});
第一个依赖项是mockserver.js文件,并使其放入localService文件夹中。
我们将要实现的mockserver依赖关系是我们的本地测试服务器。它的init方法在我们加载组件之前被立即调用。通过这种方式,我们可以捕获将发送到“真正的”服务的所有请求,并在使用mockServer.html文件启动应用程序时由测试服务器在本地处理它们。组件本身不需要
“知道”它现在将在测试模式下运行。
webapp/localService/mockdata/Invoices.json (New)
[
{
"ProductName": "Pineapple",
"Quantity": 21,
"ExtendedPrice": 87.2000,
"ShipperName": "Fun Inc.",
"ShippedDate": "2015-04-01T00:00:00",
"Status": "A"
},
{
"ProductName": "Milk",
"Quantity": 4,
"ExtendedPrice": 9.99999,
"ShipperName": "ACME",
"ShippedDate": "2015-02-18T00:00:00",
"Status": "B"
},
{
"ProductName": "Canned Beans",
"Quantity": 3,
"ExtendedPrice": 6.85000,
"ShipperName": "ACME",
"ShippedDate": "2015-03-02T00:00:00",
"Status": "B"
},
{
"ProductName": "Salad",
"Quantity": 2,
"ExtendedPrice": 8.8000,
"ShipperName": "ACME",
"ShippedDate": "2015-04-12T00:00:00",
"Status": "C"
},
{
"ProductName": "Bread",
"Quantity": 1,
"ExtendedPrice": 2.71212,
"ShipperName": "Fun Inc.",
"ShippedDate": "2015-01-27T00:00:00",
"Status": "A"
}
]
发票的Json文件类似于我们之前在webapp文件夹中的文件。只需复制内容并删除带有关键发票的外部对象结构,以便该文件由发票项的平面数组组成。之后,我们的服务器将自动读取这个文件。移除旧发票。Json文件,它不再使用。
webapp/localService/metadata.xml (New)
<edmx:Edmx Version="1.0" xmlns:edmx="http://schemas.microsoft.com/ado/2007/06/edmx">
<edmx:DataServices m:DataServiceVersion="1.0" m:MaxDataServiceVersion="3.0"
xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
<Schema Namespace="NorthwindModel" xmlns="http://schemas.microsoft.com/ado/2008/09/edm">
<EntityType Name="Invoice">
<Key>
<PropertyRef Name="ProductName"/>
<PropertyRef Name="Quantity"/>
<PropertyRef Name="ShipperName"/>
</Key>
<Property Name="ShipperName" Type="Edm.String" Nullable="false" MaxLength="40" FixedLength="false"
Unicode="true"/>
<Property Name="ProductName" Type="Edm.String" Nullable="false" MaxLength="40" FixedLength="false"
Unicode="true"/>
<Property Name="Quantity" Type="Edm.Int16" Nullable="false"/>
<Property Name="ExtendedPrice" Type="Edm.Decimal" Precision="19" Scale="4"/>
</EntityType>
</Schema>
<Schema Namespace="ODataWebV2.Northwind.Model" xmlns="http://schemas.microsoft.com/ado/2008/09/edm">
<EntityContainer Name="NorthwindEntities" m:IsDefaultEntityContainer="true" p6:LazyLoadingEnabled="true"
xmlns:p6="http://schemas.microsoft.com/ado/2009/02/edm/annotation">
<EntitySet Name="Invoices" EntityType="NorthwindModel.Invoice"/>
</EntityContainer>
</Schema>
</edmx:DataServices>
</edmx:Edmx>
元数据文件包含关于服务接口的信息,不需要手工编写。通过“真正的”服务中访问它,通过调用服务URL并在末尾添加 m e t a d a t a ( 例 如 在 我 们 的 例 子 中 是 h t t p : / / s e r v i c e s . o d a t a . o r g / V 2 / N o r t h w i n d / N o r t h w i n d . s v c / metadata(例如在我们的例子中是http://services.odata.org/V2/Northwind/Northwind.svc/ metadata(例如在我们的例子中是http://services.odata.org/V2/Northwind/Northwind.svc/metadata)。模拟服务器将读取这个文件来模拟真实的OData服务,并将从本地源文件返回正确格式的结果,以便应用程序可以使用它(XML或JSON格式)。
如果想要简单一些,需要我们从原始 Northwind OData元数据文档中删除不需要的所有内容。因为它在真正的Northwind服务中不可用,我们元数据中添加了状态字段。
webapp/localService/mockserver.js (New)
sap.ui.define([
"sap/ui/core/util/MockServer",
"sap/base/util/UriParameters"
], function (MockServer, UriParameters) {
"use strict";
return {
init: function () {
// create
var oMockServer = new MockServer({
rootUri: "https://services.odata.org/V2/Northwind/Northwind.svc/"
});
var oUriParameters = new UriParameters(window.location.href);
// configure mock server with a delay
MockServer.config({
autoRespond: true,
autoRespondAfter: oUriParameters.get("serverDelay") || 500
});
// simulate
var sPath = "../localService";
oMockServer.simulate(sPath + "/metadata.xml", sPath + "/mockdata");
// start
oMockServer.start();
}
};
});
现在我添加OData服务描述文件metadata.xml文件,就可以编写代码来初始化模拟服务器,然后模拟到真实的Northwind服务器的任何OData请求。我们装入标准SAPUI5 MockServer 模块作为依赖项,并创建一个helper对象,该对象定义了一个init方法来启动服务器。此方法在上面的mockServer.html文件中的组件初始化之前调用。init方法创建了一个MockServer实例,其URL与实际服务调用相同。
配置参数 rootUri 中的URL必须与清单中为数据源定义的uri完全相同。json描述文件,这可以是绝对URL,也可以是 ,例如,在SAP Web IDE中一个相对的URL。URL现在将由我们的测试服务器代替实际服务器。接下来,我们设置两个全局配置设置,告诉服务器自动响应,并引入1秒的延迟来模拟典型的服务器响应时间。另外,我们将手动模拟MockServer,调用响应方法。要模拟服务,我们可以简单地调用MockServer实例,以及我们新创建的metadata.xml的路径。这将从本地文件系统读取测试数据,并设置模仿真实服务的URL模式。
最后,我们在oMockServer上调用start。从这一点开始,每个到URL模式rootUri的请求都将由MockServer处理。如果您在浏览器中从index.html文件切换到mockServer.html文件,您现在可以看到测试数据再次从本地源显示出来,但是有一小段延迟。延迟可以用URI参数serverDelay指定,默认值是1秒。
这种方法非常适合本地测试,即使没有任何网络连接。通过这种方式,您的开发不依赖于远程服务器的可用性,也可以运行您的测试。
试着用index.html文件和mockServer.html文件调用这个应用,看看有什么不同。如果无法建立真正的服务连接,例如没有网络连接时,您总是可以返回到本地测试页面。
注意:
webapp/test文件夹只包含非生产性代码。
模拟数据和启动MockServer的脚本存储在webapp/localService文件夹中。
启动MockServer的脚本称为MockServer .js。