【发布时间】:2009-01-24 19:40:15
【问题描述】:
我基本上是在尝试自学如何编码,并且我想遵循良好的做法。单元测试有明显的好处。在单元测试方面也有很多狂热,我更喜欢更实用的编码和生活方法。作为上下文,我目前正在编写我的第一个“真实”应用程序,它是使用 asp.net MVC 的无处不在的博客引擎。我通过自己的调整松散地遵循 MVC Storefront 架构。因此,这是我第一次真正尝试模拟对象。我将代码示例放在问题的末尾。
如果我有任何见解或外部资源,我将不胜感激,以增加我对测试和模拟基础知识的理解。我在网上找到的资源通常是针对嘲笑的“方式”,我需要更多地了解嘲笑的地点、原因和时间。如果这不是问这个问题的最佳地点,请指点我一个更好的地方。
我试图了解我从以下测试中获得的价值。 UserService 依赖于 IUserRepository。服务层的价值是将逻辑与数据存储分开,但在这种情况下,大多数 UserService 调用只是直接传递给 IUserRepository。没有太多实际逻辑可以测试的事实也可能是我担心的根源。我有以下顾虑。
- 感觉代码只是在测试模拟框架是否正常工作。
- 为了模拟出依赖关系,这使我的测试对 IUserRepository 实现有太多了解。这是必要的邪恶吗?
- 我实际上从这些测试中获得了什么价值?被测服务的简单性是否让我怀疑这些测试的价值。
我正在使用 NUnit 和 Rhino.Mocks,但我想要完成的工作应该相当明显。
[SetUp]
public void Setup()
{
userRepo = MockRepository.GenerateMock<IUserRepository>();
userSvc = new UserService(userRepo);
theUser = new User
{
ID = null,
UserName = "http://joe.myopenid.com",
EmailAddress = "joe@joeblow.com",
DisplayName = "Joe Blow",
Website = "http://joeblow.com"
};
}
[Test]
public void UserService_can_create_a_new_user()
{
// Arrange
userRepo.Expect(repo => repo.CreateUser(theUser)).Return(true);
// Act
bool result = userSvc.CreateUser(theUser);
// Assert
userRepo.VerifyAllExpectations();
Assert.That(result, Is.True,
"UserService.CreateUser(user) failed when it should have succeeded");
}
[Test]
public void UserService_can_not_create_an_existing_user()
{
// Arrange
userRepo.Stub(repo => repo.IsExistingUser(theUser)).Return(true);
userRepo.Expect(repo => repo.CreateUser(theUser)).Return(false);
// Act
bool result = userSvc.CreateUser(theUser);
// Assert
userRepo.VerifyAllExpectations();
Assert.That(result, Is.False,
"UserService.CreateUser() allowed multiple copies of same user to be created");
}
【问题讨论】:
标签: unit-testing mocking