如何从起订量亚马逊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);
}
}
这看起来像具有读取XML文件,然后从XML反序列化它所需的对象类型的一个简单的例子。
更重要的是,你可以抽象背后,如果没有代码紧密耦合,以实现方面进行你想要的行为的服务。
对待的MWS作为第三部分服务和包装,一个抽象的背后,你有完全控制权。这样,您可以在测试时配置所需的行为。
谢谢。一旦我收拾完东西,会更新我的代码示例。 – ifinlay
的C# client library已经有好几年,作品的权利开箱。您不必处理任何XML,包含反序列化。如果你不想使用他们的代码,但想看看它是如何完成的,将它打开到Visual Studio中,并复制你想要的部分。我已经使用了所有的C#库,它们非常好。你找到你想要的操作并取消注释他们的代码并运行。我相信他们已经从各种操作中获取了所有响应的XML数据样本。
感谢您花时间回复。我也成功地使用了这些库,并且生活了几个项目。这里的问题是我试图创建模拟API响应的单元测试,以便结果可预测。因此,我试图获取真正的API响应,将其存储并在测试中重新使用。我使用MWS暂存器和编辑器获取并存储到一个xml文件。但我无法弄清楚如何将文件内容强制转换为ListMatchProductsResponse对象。 – ifinlay
基于从@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(); } } } }
}
提供一个[MCVE](代码),演示场景,更好地解释了你的问题。 – Nkosi
@Nkosi全部完成。 – ifinlay
这看起来像一个简单的情况,必须读取将XML从XML反序列化到所需对象类型的XML文件。只是想确保我明白你想做什么。 – Nkosi