我正在使用 .NET 4、NUnit 和 Rhino 模拟。我想对我的新闻存储库进行单元测试,但我不确定如何去做。我的新闻存储库是我最终将用来与数据库通信的内容。我想用它来测试假/虚拟数据。不知道可不可以??这是我目前拥有的:
public interface INewsRepository
{
IEnumerable<News> FindAll();
}
public class NewsRepository : INewsRepository
{
private readonly INewsRepository newsRepository;
public NewsRepository(INewsRepository newsRepository)
{
this.newsRepository = newsRepository;
}
public IEnumerable<News> FindAll()
{
return null;
}
}
我的单元测试是这样的:
public class NewsRepositoryTest
{
private INewsRepository newsRepository;
[SetUp]
public void Init()
{
newsRepository = MockRepository.GenerateMock<NewsRepository>();
}
[Test]
public void FindAll_should_return_correct_news()
{
// Arrange
List<News> newsList = new List<News>();
newsList.Add(new News { Id = 1, Title = "Test Title 1" });
newsList.Add(new News { Id = 2, Title = "Test Title 2" });
newsRepository.Stub(r => r.FindAll()).Return(newsList);
// Act
var actual = newsRepository.FindAll();
// Assert
Assert.AreEqual(2, actual.Count());
}
}
在上面的代码中,我不确定我需要模拟什么。上面的代码编译但在 NUnit GUI 中关于构造函数值失败。我只能假设它与我需要提供给 NewsRepository 的 INewsRepository 参数有关。我不知道如何在测试中做到这一点。有人可以纠正我的单元测试,以便它通过 NUnit GUI 吗?有人还可以就我是否正确实现存储库提供一些反馈吗?
作为模拟的新手,有什么我需要验证的吗?我什么时候需要验证?它的目的是什么?我一直在研究几个源代码项目,有些使用了验证,有些则没有。
如果上述测试通过,这对作为开发人员的我来说意味着什么?其他开发人员必须对我的存储库执行什么操作才能使其在 NUnit GUI 中失败?
很抱歉所有问题,但他们是新手问题:)
我希望有人能帮助我。
最佳答案
正如 Steven 所说,您在上面的代码中针对 Mock NewsRepository Assert
ing。
模拟的想法是隔离被测代码并创建假代码来替换它们的依赖项。
您使用 Mock NewsRepository 来测试使用 INewsRepository
的内容,在您的情况下,您提到了 NewsService
; NewsService
将使用您模拟的 INewsRepository
。
如果您在解决方案中搜索任何使用 INewsRepository.FindAll() 的内容,您将创建一个模拟存储库来单独测试该代码。
如果你想测试调用你的服务层的东西,你需要模拟 NewsService
。
此外,正如 Steven 所说,NewsRepository
不需要由 IoC 注入(inject)其自身的副本,因此:
public class NewsRepository : INewsRepository
{
private readonly INewsRepository newsRepository;
public NewsRepository(INewsRepository newsRepository)
{
this.newsRepository = newsRepository;
}
public IEnumerable<News> FindAll()
{
return null;
}
}
应该变成:
public class NewsRepository : INewsRepository
{
public IEnumerable<News> FindAll()
{
return null;
}
}
一旦您的 FindAll() 方法中有需要测试的功能,您就可以模拟他们使用的对象。
作为伟大的风格点Art Of Unit Testing模拟对象的初始化最好从 Setup 方法中删除,并在方法开始时调用的辅助方法中执行。由于对 Setup 的调用将是不可见的,并且使模拟的初始化不清楚。
作为风格的另一点,从那本书中,建议的单元测试命名约定是:“MethodUnderTest_Scenario_ExpectedBehavior”。 所以,
FindAll_should_return_correct_news
可以变成,例如:
FindAll_AfterAddingTwoNewsItems_ReturnsACollectionWithCountOf2
我希望这能让方法更清晰。
关于c# - 单元测试存储库需要帮助/建议,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4398723/