咱們只是在一個真實的服務上運行咱們的應用程序,可是對於開發和測試咱們的應用程序,咱們不但願依賴於「真實」服務的可用性,或者在數據服務所在的系統上增長額外的負載。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