C# 单元测试,检查调用服务层的操作方法
我有一个名为NewsController的控制器,该控制器的构造函数接收一个INewsService作为参数 我在这个控制器中有一个名为GetAllNews()的方法,它返回一个JSON结果,我用它来填充YUI数据表。我想编写一个单元测试,检查是否调用了新闻服务的FindAll方法来返回所有新闻项。我该怎么做?我目前拥有的是:C# 单元测试,检查调用服务层的操作方法,c#,asp.net-mvc,unit-testing,nunit,C#,Asp.net Mvc,Unit Testing,Nunit,我有一个名为NewsController的控制器,该控制器的构造函数接收一个INewsService作为参数 我在这个控制器中有一个名为GetAllNews()的方法,它返回一个JSON结果,我用它来填充YUI数据表。我想编写一个单元测试,检查是否调用了新闻服务的FindAll方法来返回所有新闻项。我该怎么做?我目前拥有的是: public JsonResult GetAllNews() { var items = newsService.FindAll(); var jsonRes
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();
}
如果您可以侥幸逃脱,就不要单元测试是否调用了特定的方法。单元测试的目的是测试行为,而不是实现。测试调用
FindAll
就是测试一个实现。这会导致脆弱的测试,如果您更改了实现,但行为没有更改,测试就会中断。客户不在乎你如何让他们知道所有的新闻,他们只希望你让他们知道所有的新闻
所以
应该是
public void GetAllNews_should_get_all_the_news
我将把编码的细节留给您来决定。如果您可以侥幸逃脱,请不要对调用的特定方法进行单元测试。单元测试的目的是测试行为,而不是实现。测试调用
FindAll
就是测试一个实现。这会导致脆弱的测试,如果您更改了实现,但行为没有更改,测试就会中断。客户不在乎你如何让他们知道所有的新闻,他们只希望你让他们知道所有的新闻
所以
应该是
public void GetAllNews_should_get_all_the_news
我将把编码的细节留给您。正如其他人所指出的,从长远来看,测试特定的方法调用可能很脆弱
然而,从Rhino.Mocks的角度来看,如果您想检查期望值,应该使用Mock而不是存根。将您的
GenerateStub
更改为GenerateMock
,将您的.Stub()
调用更改为.Expect()
调用。这将修复您的测试。正如其他人所指出的,从长远来看,对特定方法调用的测试可能很脆弱
然而,从Rhino.Mocks的角度来看,如果您想检查期望值,应该使用Mock而不是存根。将您的
GenerateStub
更改为GenerateMock
,将您的.Stub()
调用更改为.Expect()
调用。这将修复您的测试。您可能会发现Martin Fowler的这篇文章对mock和stub之间的差异很感兴趣
Fowler指出存根用于状态验证,而mock用于行为验证 您可能会发现Martin Fowler的这篇关于mock和stub之间差异的文章很有趣
Fowler指出存根用于状态验证,而mock用于行为验证作为一个旁注,为什么你认为这是一个有用的测试?@ BZIM:我是初学者,仍然在学习。对我来说,测试什么和不该做什么并不总是很清楚。作为一个旁白,为什么你认为这是一个有用的测试?”BZIM:我是初学者,还在学习。我并不总是清楚该测试什么,不该测试什么。你说的行为是什么意思?在我的GetAllNews()方法中会有什么行为?如果您将测试命名为GetAllNews,那么您应该在测试代码中包含什么?你能在上面的回答中提供一些示例代码吗?你指的是行为吗?在我的GetAllNews()方法中会有什么行为?如果您将测试命名为GetAllNews,那么您应该在测试代码中包含什么?你能在上面的回答中提供一些示例代码吗?mock和stub的区别是什么?何时使用这两个?存根用于提供固定的响应。模拟用于验证预期。您可以使用mock提供固定的响应,但是存根不跟踪方法调用,因此不能用于验证期望。mock和存根之间的区别是什么?何时使用这两个?存根用于提供固定的响应。模拟用于验证预期。您可以使用mock提供固定的响应,但存根不跟踪方法调用,因此不能用于验证期望。
public void GetAllNews_should_get_all_the_news