【发布时间】:2014-01-06 18:02:05
【问题描述】:
给定以下课程和测试
public class UserService
{
private IUserRepository _userRepo;
public UserService(IUserRepository userRepo)
{
_userRepo = userRepo;
}
public User Get(int id)
{
var user = _userRepo.Get(id);
if(user == null)
throw new CustomException();
return user;
}
}
单元测试:
[Fact]
public void MissingUser_ThrowsException()
{
// Arrange
var userService = new UserService(null);
// Act
Action result = userService.Get(0);
// Assert
result.Throws<CustomException>();
}
[Fact]
public void ExistingUser_ReturnsUser()
{
// Arrange
var user = new User()
{
Id = 0
};
var userRepo = new Mock<IUserRepository>();
userRepo
.Setup(m => m.Get(0))
.Return(user);
var userService = new UserService(userRepo.Object);
// Act
var result = userService.Get(0);
// Assert
Assert.Equal(user, result);
}
当我知道在测试中不会调用依赖项时,有没有办法避免将空参数传递给构造函数?如果被测类现在需要一个新的构造函数参数,我需要向这个测试和所有其他不使用该依赖项的测试添加另一个 null 参数。
更新:
我正在使用Moq 和XUnit。也就是说,我想避免使用设置方法,因为我同意XUnit 的理念。但是,任何模拟框架仍然存在同样的问题。
我添加了另一个使用模拟的测试。我试图避免的情况是,当我不需要时,必须处理向被测类的构造函数添加额外的参数。
如果我要在 UserService 方法使用的 UserService 的构造函数中添加另一个依赖项,我只希望第二个测试在运行时失败。目前,我需要为这两个测试添加另一个参数到 UserService 的 ctor。
我对此想得越多,我就越意识到我想使用 IoC 来构建我的具体(被测类)。是否推荐在单元测试中使用 DI/IoC 容器?
【问题讨论】:
-
听起来您正在寻找Mock framework
-
如果模拟框架因您的情况而过度杀戮,您可以只运行一个在每个测试方法之前调用的设置
-
我用更多细节更新了我的问题。
标签: c# unit-testing