2017-04-26 73 views
2

語境如何從起訂量亞馬遜MWS響應單元測試

我的單元測試調用(使用MWSClientCsRuntime)亞馬遜MWS API在ListMatchingProducts操作的C#.NET類。

問題

亞馬遜MWS API與產品數據隨時都在變化,所以我想能夠起訂量的ListMatchingProductsResponse對象API返回一個移動的目標。我可以使用MWS暫存器獲取API響應,並將它們存儲在xml文件中。但隨後,在單元測試中,我需要從這些文件中的數據對象轉換成一個ListMatchingProductsResponse對象。

問題

我怎麼能這個XML數據加載到ListMatchingProductsResponse對象? (我注意到,對象具有ReadFragmentsFrom方法,但我看不出這可能是使用)。

代碼

[TestClass] 
public class PossibleAmazonProductMatchesTests 
{ 
    string testDataDirectory = Directory.GetParent(Directory.GetCurrentDirectory()).Parent.FullName + @"\Test data"; 

    [TestMethod] 
    public void FindSpanners() 
    { 
     // Arrange 

     ListMatchingProductsRequest request = new ListMatchingProductsRequest("secret key", "market id", "spanner"); 
     ListMatchingProductsResult result = new ListMatchingProductsResult(); 

     ListMatchingProductsResponse response = new ListMatchingProductsResponse(); 

     string xmlString = File.ReadAllText(this.testDataDirectory + @"\Spanners Response.xml"); 

     // *** The issue - How do I coerce xmlString into response? *** 

     var client = new Mock<MarketplaceWebServiceProductsClient>(); 
     client.Setup(c => c.ListMatchingProducts(request)).Returns(response); 

     // Act 

     // This is the method being tested. It calls ListMatchingProducts which is being mocked. 
     PossibleAmazonProductMatches possibleAmazonProductMatches = new PossibleAmazonProductMatches("spanners", client); 

     // Assert 

     Assert.IsTrue(possibleAmazonProductMatches.SpannersFound == true); 
    } 
} 
+0

提供一個[MCVE](代碼),演示場景,更好地解釋了你的問題。 – Nkosi

+0

@Nkosi全部完成。 – ifinlay

+0

這看起來像一個簡單的情況,必須讀取將XML從XML反序列化到所需對象類型的XML文件。只是想確保我明白你想做什麼。 – Nkosi

回答

1

這看起來像具有讀取XML文件,然後從XML反序列化它所需的對象類型的一個簡單的例子。

更重要的是,你可以抽象背後,如果沒有代碼緊密耦合,以實現方面進行你想要的行爲的服務。

對待的MWS作爲第三部分服務和包裝,一個抽象的背後,你有完全控制權。這樣,您可以在測試時配置所需的行爲。

+0

謝謝。一旦我收拾完東西,會更新我的代碼示例。 – ifinlay

0

C# client library已經有好幾年,作品的權利開箱。您不必處理任何XML,包含反序列化。如果你不想使用他們的代碼,但想看看它是如何完成的,將它打開到Visual Studio中,並複製你想要的部分。我已經使用了所有的C#庫,它們非常好。你找到你想要的操作並取消註釋他們的代碼並運行。我相信他們已經從各種操作中獲取了所有響應的XML數據樣本。

+0

感謝您花時間回覆。我也成功地使用了這些庫,並且生活了幾個項目。這裏的問題是我試圖創建模擬API響應的單元測試,以便結果可預測。因此,我試圖獲取真正的API響應,將其存儲並在測試中重新使用。我使用MWS暫存器和編輯器獲取並存儲到一個xml文件。但我無法弄清楚如何將文件內容強制轉換爲ListMatchProductsResponse對象。 – ifinlay

0

基於從@Nkosi和@ScottG偉大的回答,我現在有這真可謂是苦不堪言簡單,儘管需要注意的幾個重點工作的解決方案。所以單元測試代碼如下:

[TestClass] 
public class PossibleAmazonProductMatchesTests 
{ 
    [TestMethod] 
    public void Test1() 
    { 
     // Arrange 

     var moqClient = new MarketplaceWebServiceProductsMock(); 

     // Act 

     PossibleAmazonProductMatches possibleAmazonProductMatches = new PossibleAmazonProductMatches("spanners", moqClient); 

     // Assert 

     Assert.IsTrue(possibleAmazonProductMatches.PossibleProductList.Count == 10); 
    } 
} 

..就是這樣。它可以得到更簡單!

對於抽象被測對象(PossibleAmazonProductMatches)有這樣的構造:

public PossibleAmazonProductMatches(string searchTerm, MarketplaceWebServiceProducts.MarketplaceWebServiceProducts client) 
{ 
    // Some processing 
} 

重要點需要注意的是:

  • MarketplaceWebServiceProducts實際上是一個接口儘管沒有關係的事實不遵循ISomething命名約定。
  • MarketplaceWebServiceProducts還用作命名空間名稱,因此需要在PossibleAmazonProductMatches構造函數中將MarketplaceWebServiceProducts.MarketplaceWebServiceProducts語法加倍。
  • MarketplaceWebServiceProductsMock包含在MWS包中,因此沒有任何代碼。
  • 默認情況下,MarketplaceWebServiceProductsMock從埋藏在程序集中的固定xml模板文件讀取,並使用它來構建您的測試響應。您可以根據需要編輯此文件。我實際上想創建自己的MWS暫存器的xml文件,並希望將它們存儲在更方便的位置。我以爲我可以從MarketplaceWebServiceProductsMock繼承並覆蓋相關的代碼來做到這一點,但事實證明這是隱藏在私有方法中的。因此,我簡單地複製了MarketplaceWebServiceProductsMock並將其改爲符合我的需求。因此,我的模擬現在看起來是這樣的:

    using MarketplaceWebServiceProducts.Model; 
    using System; 
    using System.IO; 
    using MWSClientCsRuntime; 
    
    namespace AmazonMWS.Tests 
    { 
    public class MyMWSMock : MarketplaceWebServiceProducts.MarketplaceWebServiceProducts 
    { 
    
        // Definitions of most methods removed for brevity. They all match the pattern of ListMatchingProductsResponse. 
    
        public ListMatchingProductsResponse ListMatchingProducts(ListMatchingProductsRequest request) 
        { 
         return newResponse<ListMatchingProductsResponse>(); 
        } 
    
        private T newResponse<T>() where T : IMWSResponse 
        { 
         FileStream xmlIn = File.Open("D:\\MyTestDataFolder\\Test1.xml", FileMode.Open); 
         try 
         { 
          StreamReader xmlInReader = new StreamReader(xmlIn); 
          string xmlStr = xmlInReader.ReadToEnd(); 
    
          MwsXmlReader reader = new MwsXmlReader(xmlStr); 
          T obj = (T)Activator.CreateInstance(typeof(T)); 
          obj.ReadFragmentFrom(reader); 
          obj.ResponseHeaderMetadata = new ResponseHeaderMetadata("mockRequestId", "A,B,C", "mockTimestamp", 0d, 0d, new DateTime()); 
          return obj; 
         } 
         catch (Exception e) 
         { 
          throw MwsUtil.Wrap(e); 
         } 
         finally 
         { 
          if (xmlIn != null) { xmlIn.Close(); } 
         } 
        } 
    } 
    

    }