所以我有一些初始设置,如下所示:
ILoginManager _loginManager;
Mock<IValidations> _validations;
Mock<IAccountRepository> _accountRepository;
[SetUp]
public void Setup()
{
_loginManager = new LoginManager();
_validations = new Mock<IValidations>();
_accountRepository = new Mock<IAccountRepository>();
}
然后我有一个看起来像这样的测试方法:
[Test]
public void Login_ValidUser()
{
_validations.Setup(val => val.IsValidAccount(It.IsAny<User>())).Returns(true);
_accountRepository.Setup(repo => repo.Login(It.IsAny<User>())).Returns(()=>new User());
var result = _loginManager.Login(new User());
Assert.That(result, Is.Not.Null);
}
而实际的方法看起来像这样:
public User Login(User user)
{
if (user != null && _validations.IsValidAccount(user))
{
return _accountDal.Login(user);
}
log.Error("User null or not valid");
return null;
}
问题是测试方法仍然调用原始方法,因此它忽略了模拟设置。
这些依赖项必须直接注入管理器,以便在测试时可用于模拟
例如
public class LoginManager : ILoginManager {
private readonly IValidations _validations;
private readonly IAccountRepository _accountDal;
public LoginManager(IValidations validations, IAccountRepository accountDal) {
_validations = validations;
_accountDal = accountDal;
}
public User Login(User user) {
if (user != null && _validations.IsValidAccount(user)) {
return _accountDal.Login(user);
}
log.Error("User null or not valid");
return null;
}
}
您当前的示例未使用被测试类中的模拟,因为它们未被注入。
相应地重构LoginManager
类和测试
ILoginManager _loginManager;
Mock<IValidations> _validations;
Mock<IAccountRepository> _accountRepository;
[SetUp]
public void Setup() {
_validations = new Mock<IValidations>();
_accountRepository = new Mock<IAccountRepository>();
_loginManager = new LoginManager(_validations.Object, _accountRepository.Object);
}
[Test]
public void Login_ValidUser() {
//Arrange
var expected = new User();
_validations.Setup(val => val.IsValidAccount(It.IsAny<User>())).Returns(true);
_accountRepository.Setup(repo => repo.Login(It.IsAny<User>())).Returns(()=> user);
//Act
var actual = _loginManager.Login(expected);
//Assert
Assert.That(actual, Is.Not.Null);
Assert.AreEqual(expected, actual);
}