所以我有一些类似于以下内容的初始设置:
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;
}
问题在于测试方法仍然调用原始方法,因此它会忽略模拟设置。
答案 0 :(得分:1)
必须将这些依赖项直接注入到管理器中,以便在测试时可以将其用于模拟
例如
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);
}