尽管有模拟,测试方法仍会调用实际方法

时间:2018-09-02 16:17:19

标签: c# .net mocking nunit moq

所以我有一些类似于以下内容的初始设置:

    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;
    }

问题在于测试方法仍然调用原始方法,因此它会忽略模拟设置。

1 个答案:

答案 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);        
}