c# - 如何使用 TDD 方法创建 Restful Web 服务?

标签 c# web-services unit-testing tdd

我的任务是使用 WCF 使用以下方法使用 TDD 方法创建一个具有 JSON 格式的 Restful Web 服务,该方法应将产品作为文本文件存储在磁盘上:

CreateProduct(Product product)
GetAProduct(int productId) 


URI Templates:
POST to /MyService/Product
GET to /MyService/Product/{productId}

创建服务及其 web 方法是简单的部分,但是

您将如何使用 TDD 处理此任务?您应该在创建 SUT 代码之前创建一个测试。

单元测试的规则说它们也应该是独立的和可重复的。

我有以下一些困惑和问题:

1) 我应该通过添加对实际服务实现的引用来编写我的单元测试,还是针对服务的 URL(在这种情况下我必须托管和运行服务)?还是两者兼而有之?

2) 我在想一种方法可能只是创建一个测试方法,我在其中创建一个产品,调用 CreateProduct() 方法,然后调用 GetAProduct() 方法并断言发送的产品是我收到的产品。在 TearDown() 事件中,我只是删除了创建的产品。

但是我遇到的问题是

  • 它测试了多个功能,因此它并不是真正的单元测试。
  • 它不检查数据是否正确存储在文件中
  • 是 TDD 吗?

如果我为每个 Web 方法创建一个单独的单元测试,例如调用 GetAProduct() Web 方法,我必须将一些测试数据物理存储在服务器上,因为它不能依赖 CreateProduct()单元测试。它们应该能够独立运行。

请指教。

谢谢,

最佳答案

我建议不要担心 Web 服务端点并关注系统的行为。为了本次讨论,我将放弃所有技术术语,并讨论我认为您试图解决的核心业务问题:创建产品目录。

要做到这一点,首先要考虑产品目录的作用,而不是有关如何操作的技术细节。将其用作测试的起点。

public class ProductCatalogTest
{
    [Test]
    public void allowsNewProductsToBeAdded() {}

    [Test]
    public void allowsUpdatesToExistingProducts() {}

    [Test]
    public void allowsFindingSpecificProductsUsingSku () {}
}

我不会在这里详细介绍如何实现测试和生产代码,但这是一个起点。完成 ProductCatalog 生产类后,您可以将注意力转移到技术细节上,例如制作 Web 服务和编码 JSON。

我不是 .NET 专家,所以这主要是伪代码,但最终可能看起来像这样。

public class ProductCatalogServiceTest
{
   [Test]
   public void acceptsSkuAsParameterOnGetRequest()
   {
       var mockCatalog = new MockProductCatalog(); // Hand rolled mock here.
       var catalogService = new ProductCatalogService(mockCatalog);

       catalogService.find("some-sku-from-url")

       mockCatalog.assertFindWasCalledWith("some-sku-from-url");
   }

   [Test]
   public void returnsJsonFromGetRequest()
   {
       var mockCatalog = new MockProductCatalog(); // Hand rolled mock here.
       mockCatalog.findShouldReturn(new Product("some-sku-from-url"));
       var mockResponse = new MockHttpResponse(); // Hand rolled mock here.

       var catalogService = new ProductCatalogService(mockCatalog, mockResponse);

       catalogService.find("some-sku-from-url")

       mockCatalog.assertWriteWasCalledWith("{ 'sku': 'some-sku-from-url' }");
   }
}

您现在已经完成了端到端的测试,并且测试了整个过程。我个人会测试 ProductCatalog 中包含的业务逻辑,并且可能会跳过测试编码(marshal)处理,因为它很可能全部由框架完成,并且只需很少的代码即可将 Controller 绑定(bind)到产品目录中。您的里程可能会有所不同。

最后,在测试驱动目录时,我希望代码被分成多个类,并且模拟会在那里发挥作用,以便对它们进行单元测试,而不是大型集成测试。同样,这是另一天的话题。

希望对您有所帮助!

布兰登

关于c# - 如何使用 TDD 方法创建 Restful Web 服务?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13771750/

相关文章:

c# - 限制对远程 api 的并行请求

c - 如何最好地部署用 C 编写的 Web 应用程序?

web-services - 如何模拟 WS 客户端并在 Camel route 提供响应

c++ - 什么 C++ 设计模式可用于在生产代码和测试代码之间交换函数模板的行为?

java - 不使用 InjectMocks 创建对象会导致 httpClient 出现问题

c# - 如何使 WinForms UserControl 填充其容器的大小

c# - ScopeLock 模式 : Struct or Class?

c# - 样式化扩展工具包 BusyIndi​​cator

Java 网络服务 "HTTP status 404"- Eclipse、Apache、Tomcat

objective-c - OCUnit 中的简化断言