【问题标题】:Unit test to check if an action method called the service layer单元测试以检查是否有调用服务层的操作方法
【发布时间】:2010-12-13 13:54:41
【问题描述】:

我有一个名为 NewsController 的控制器,这个控制器的构造函数接收一个 INewsService 作为参数。

我在这个控制器中有一个名为 GetAllNews() 的方法,它返回我用来填充 YUI 数据表的 JSON 结果。我想编写一个单元测试来检查是否调用了新闻服务的 FindAll 方法来返回所有新闻项目。我该怎么做?我目前拥有的是:

public JsonResult GetAllNews()
{
   var items = newsService.FindAll();
   var jsonResult = Json(items);

   return jsonResult;
}

我的控制器单元测试如下:

public NewsControllerTest()
{
   newsServiceStub = MockRepository.GenerateStub<INewsService>();
   newsController = new NewsController(newsServiceStub);
}

[Test]
public void GetAllNews_should_use_news_service()
{
   // Arrange
   List<News> newsList = new List<News>();
   newsServiceStub.Stub(s => s.FindAll()).Return(newsList);

   // Act
   var actual = newsController.GetAllNews();

   // Assert
   newsServiceStub.VerifyAllExpectations();
}

上面的代码测试通过了。但是,如果我将 GetAllNews() 更改为如下所示,那么它也会通过。不应该失败吗?我要测试的是 GetAllNews() 是否使用新闻服务:

public JsonResult GetAllNews()
{
   return null;
}

【问题讨论】:

  • 附带说明,您为什么认为这是一个有用的测试?
  • @bzim:我是初学者,还在学习。我并不总是很清楚要测试什么,不测试什么。

标签: c# asp.net-mvc unit-testing nunit


【解决方案1】:

如果您能侥幸成功,请不要对某个特定方法被调用进行单元测试。单元测试的重点是测试行为,而不是实现。测试调用FindAll 是测试实现。如果您更改实现但行为没有改变,这会导致脆弱的测试中断。客户不在乎您如何获得所有新闻,他们只是希望您获得所有新闻。

所以

public void GetAllNews_should_use_news_service()

应该是

public void GetAllNews_should_get_all_the_news

我将把编码的细节留给你。

【讨论】:

  • 你的意思是行为?我的 GetAllNews() 方法会有什么行为?如果您将测试命名为 GetAllNews_should_get_all_the_news,您会在测试代码中包含什么?您能否在上面的答案中提供一些示例代码?
【解决方案2】:

正如其他人所指出的,从长远来看,对特定方法调用的测试可能会很脆弱。

但是,从 Rhino.Mocks 的角度来看,如果您想检查期望值,您应该使用 Mock 而不是 Stub。将您的GenerateStub 更改为GenerateMock 并将您的.Stub() 电话更改为.Expect() 电话。这应该可以解决您的测试问题。

【讨论】:

  • 模拟和存根有什么区别?我什么时候使用这两个?
  • 存根用于提供预设响应。模拟用于验证期望。您可以使用模拟来提供预设响应,但存根不跟踪方法调用,因此不能用于验证预期。
【解决方案3】:

您可能会发现 Martin Fowler 的这篇文章对模拟和存根之间的区别很感兴趣。

http://www.martinfowler.com/articles/mocksArentStubs.html

Fowler 指出存根用于状态验证,而模拟用于行为验证

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多