2017-04-26 81 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(); } 
         } 
        } 
    } 
    

    }