咱们只是在一个真实的服务上运行咱们的应用程序,可是对于开发和测试咱们的应用程序,咱们不但愿依赖于“真实”服务的可用性,或者在数据服务所在的系统上增长额外的负载。html
这个系统就是所谓的后端系统,咱们如今将使用一个称为mock server的SAPUI5特性来模拟它。它为本地文件提供服务,但它模拟后端系统比加载本地数据更实际。咱们还将更改模型实例化部分,以便模型在描述符中配置,并由SAPUI5自动实例化。这样,咱们就不须要关心代码中的模型实例化。web
Previewjson
The list of invoices is now served by the Mock Serverbootstrap
Coding后端
You can view and download all files at Walkthrough - Step 27.api
Folder Structure for this Step数组
在这一步以后,咱们app项目的文件夹结构将测试文件和生产文件清晰地分开。新的测试文件夹如今包含一个新的HTML页面mockServer。它将在测试模式下启动咱们的应用程序,而无需调用真正的服务。浏览器
新的localService文件夹包含一个元数据。用于模拟服务器OData的xml服务描述文件。使用本地数据模拟实际服务的 mockserver.js文件,以及包含本地测试数据的mockdata子文件夹(invoice .json)。服务器
webapp/test/mockServer.html (New)网络
<!DOCTYPE html> <html> <head> <metahttp-equiv="X-UA-Compatible"content="IE=edge"> <metacharset="utf-8"> <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-libs="sap.m" data-sap-ui-compatVersion="edge" data-sap-ui-preload="async" data-sap-ui-resourceroots='{ "sap.ui.demo.walkthrough": "../" }'> </script> <script> sap.ui.getCore().attachInit(function(){ sap.ui.require([ "sap/ui/demo/walkthrough/localService/mockserver", "sap/m/Shell", "sap/ui/core/ComponentContainer" ],function(mockserver,Shell,ComponentContainer){ mockserver.init(); newShell({ app :newComponentContainer({ name :"sap.ui.demo.walkthrough", settings :{ id :"walkthrough" } }) }).placeAt("content"); }); }); </script> </head> <bodyclass="sapUiBody"id="content"> </body> </html>
复制index.html到webapp/test文件夹中的一个单独文件,并将其命名为mockServer.html。如今咱们将使用这个文件在测试模式下运行咱们的应用程序,从JSON文件加载模拟数据。测试页面不该该放在应用程序根文件夹中,而应该放在测试文件夹中,以便清楚地将生产代码和测试代码分开。
从如今开始,您有两个不一样的入口页面:一个用于真正的“链接”应用程序(index.html),另外一个用于本地测试(mockServer.html)。您能够自由决定是对实际服务数据仍是对应用程序中的本地数据执行下一步操做。
请注意:若是到实际服务的链接不可用,或者前面步骤中的代理配置不起做用,则始终可使用mockServer.html文件。这将显示带有模拟测试数据的应用程序。index.html文件老是从远程服务器加载数据。若是请求失败,发票列表将保持空。
webapp/test/mockServer.html
<!DOCTYPE html> <html> <head> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta charset="utf-8"> <title>Walkthrough - Test page</title> <script id="sap-ui-bootstrap" src="/resources/sap-ui-core.js" data-sap-ui-theme="sap_belize" data-sap-ui-libs="sap.m" data-sap-ui-bindingSyntax="complex" data-sap-ui-compatVersion="edge" data-sap-ui-preload="async" data-sap-ui-resourceroots='{ "sap.ui.demo.walkthrough": "../" }'> </script> <script> sap.ui.getCore().attachInit(function () { sap.ui.require([ "sap/ui/demo/walkthrough/localService/mockserver", "sap/m/Shell", "sap/ui/core/ComponentContainer" ],function(mockserver,Shell,ComponentContainer){ mockserver.init(); new Shell({ app : new ComponentContainer({ height: "100%", name: "sap.ui.demo.walkthrough" }) }).placeAt("content"); }); }); </script> </head> <body class="sapUiBody" id="content"> </body> </html>
咱们修改mockServer.html文件,并更改页面标题,以将其与生产启动页区分开来。在引导过程当中,因为mockServer的缘由,data-sap-ui-resourceroots属性也略有更改。html文件再也不直接在webapp文件夹中。
此外,咱们将组件的初始化切换到sap.ui.require语法,由于咱们如今须要加载更多启动应用程序所需的额外文件。第一个依赖项是名为mockserver.js的文件。稍后将位于localService文件夹中的。咱们还切换到require语句为实例化Shell和ComponentContainer提供的依赖项,而不是将完整的名称空间用于sap.m.Shell和sap.ui.core.ComponentContainer。
新mockserver.js咱们刚刚加载并即将实现的资源是咱们的本地测试服务器。它的init方法在咱们实际定义组件以前当即被调用。经过这种方式,咱们能够捕获全部将进入“real”服务的请求,并在使用mockServer.html文件启动应用程序时经过测试服务器本地处理它们。组件自己并不“知道”它如今将在测试模式下运行。
模拟服务器不须要从代码中的任何其余地方调用,所以咱们使用sa .ui。须要异步加载依赖项,而不须要定义全局名称空间。
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"
}
]
清理旧Invoices.json文件从webapp文件夹,它已再也不使用。 Invoices.json 文件相似于webapp文件夹中的前一个文件。只需复制内容并删除带有关键发票的外部对象结构,以便该文件由一个包含发票项的平面数组组成。此文件将在本步骤稍后由服务器自动读取。
webapp/localService/metadata.xml (New)
<edmx:EdmxVersion="1.0"xmlns:edmx="http://schemas.microsoft.com/ado/2007/06/edmx"> <edmx:DataServicesm:DataServiceVersion="1.0"m:MaxDataServiceVersion="3.0" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"> <SchemaNamespace="NorthwindModel"xmlns="http://schemas.microsoft.com/ado/2008/09/edm"> <EntityTypeName="Invoice"> <Key> <PropertyRefName="ProductName"/> <PropertyRefName="Quantity"/> <PropertyRefName="ShipperName"/> </Key> <PropertyName="ShipperName"Type="Edm.String"Nullable="false"MaxLength="40"FixedLength="false" Unicode="true"/> <PropertyName="ProductName"Type="Edm.String"Nullable="false"MaxLength="40"FixedLength="false" Unicode="true"/> <PropertyName="Quantity"Type="Edm.Int16"Nullable="false"/> <PropertyName="ExtendedPrice"Type="Edm.Decimal"Precision="19"Scale="4"/> </EntityType> </Schema> <SchemaNamespace="ODataWebV2.Northwind.Model"xmlns="http://schemas.microsoft.com/ado/2008/09/edm"> <EntityContainerName="NorthwindEntities"m:IsDefaultEntityContainer="true"p6:LazyLoadingEnabled="true" xmlns:p6="http://schemas.microsoft.com/ado/2009/02/edm/annotation"> <EntitySetName="Invoices"EntityType="NorthwindModel.Invoice"/> </EntityContainer> </Schema> </edmx:DataServices> </edmx:Edmx>
元数据文件包含关于服务接口的信息,不须要手工编写。能够经过调用服务URL并在末尾添加$metadata(例如,在咱们的示例http://services.odata.org/v2/northwind/northwind.svc/$ metadata)直接从“真实”服务访问它。mock服务器将读取这个文件来模拟实际的OData服务,并以适当的格式返回来自本地源文件的结果,以便应用程序可使用它(XML或JSON格式)。
为了简单起见,咱们从原来的Northwind OData元数据文档中删除了场景中不须要的全部内容。咱们还将status字段添加到元数据中,由于它在真正的Northwind服务中不可用。
webapp/localService/mockserver.js (New)
sap.ui.define([ "sap/ui/core/util/MockServer" ],function(MockServer){ "use strict"; return{ init:function(){ // create var oMockServer =newMockServer({ rootUri:"https://services.odata.org/V2/Northwind/Northwind.svc/" }); var oUriParameters = jQuery.sap.getUriParameters(); // configure MockServer.config({ autoRespond:true, autoRespondAfter: oUriParameters.get("serverDelay")||1000 }); // simulate var sPath = jQuery.sap.getModulePath("sap.ui.demo.walkthrough.localService"); oMockServer.simulate(sPath +"/metadata.xml", sPath +"/mockdata"); // start oMockServer.start(); } }; });
如今咱们已经添加了OData服务描述文件元数据。在xml文件中,咱们能够编写代码来初始化模拟服务器,而后模拟对真正的Northwind服务器的任何OData请求。
咱们将MockServer模块做为依赖项加载,并建立一个helper对象,该对象定义一个init方法来启动服务器。此方法在mockServer.html文件中的组件初始化以前调用init方法,使用与实际服务调用相同的URL建立一个MockServer实例。
配置参数rootURI.json中的URL文件描述符必须与清单中为数据源定义的uri彻底相同。这能够是一个绝对URL,也能够是一个相对URL,例如在SAP Web IDE中。URL如今将由咱们的测试服务器而不是实际服务提供。接下来,咱们设置两个全局配置设置,告诉服务器自动响应,并引入1秒延迟来模拟典型的服务器响应时间。不然,咱们将不得不手动调用MockServer上的response方法来模拟调用。
要模拟服务,只需在MockServer实例上调用模拟方法,并提供到新建立的元数据.xml的路径。这将从本地文件系统读取测试数据,并设置URL模式来模拟实际服务。
最后,咱们调用oMockServer上的start。从如今开始,对URL模式rootURI的每一个请求都将由MockServer处理。若是你从索引中切换。到mockServer的html文件。浏览器中的html文件,如今您能够看到测试数据再次从本地源显示出来,可是延迟较短。延迟能够用URI参数serverDelay指定,默认值是1秒。
这种方法很是适合本地测试,即便没有任何网络链接。这样,您的开发就不依赖于远程服务器的可用性,即运行测试。
尝试使用索引调用应用程序。html文件和模型服务器。查看html文件的区别。若是没法进行真正的服务链接,例如在没有网络链接的状况下,您老是能够回到本地测试页面。
Conventions
▪webapp/test文件夹只包含非生产性代码。
▪Mock数据和启动MockServer的脚本存储在webapp/localService文件夹中。
▪启动MockServer的脚本称为MockServer .js。
Parent topic: Walkthrough
Previous: Step 26: (Optional) Remote OData Service
Next: Step 28: Unit Test with QUnit
Related Information