1

我之前问过这个问题,关于测试控制器操作并验证我的存储库中的方法是否被调用。答案回来了,我应该只在存储库的单独测试中测试在 Register 方法(都在同一个存储库中)内部调用的 Save 方法。这就是我的想法,但我来做测试,我不能让它工作。:(

这是存储库测试,我哪里出错了?

    [TestMethod]
    public void Register_calls_Save_method_when_Member_is_valid()
    {
        _mockMemberRepository.Setup(r => r.GetByEmail(It.IsAny<string>())).Returns((Member)null);            
        MembershipCreateStatus status = _mockMemberRepository.Object.Register(_testMember.Email, "password", "password");
        _mockMemberRepository.Verify(r => r.Save(It.IsAny<Member>()), Times.Once());
    }

这是存储库中的 Register 方法:

public MembershipCreateStatus Register(string email, string password, string confirm)
    {
        if (password.Equals(confirm))
        {
            try
            {
                Member m = GetByEmail(email);
                if (m == null)
                {
                    int format = (int)PasswordFormatEnum.Encrypted;
                    string salt = GenerateSalt();
                    string pass = EncodePassword(password, format, salt);

                    m = new Member()
                    {
                        Email = email,
                        Password = pass,
                        PasswordSalt = salt,
                        PasswordFormat = format
                    };
                    Save(m);
                    return MembershipCreateStatus.Success;
                }
                else
                    return MembershipCreateStatus.DuplicateEmail;
                //"A user with that email address already exists. Please use the Forgotten Password link if you need to recover your password.";
            }
            catch (Exception ex)
            {
                _logger.LogError(ex);
                return MembershipCreateStatus.ProviderError;
            }
        }
        return MembershipCreateStatus.InvalidPassword;
    }
4

1 回答 1

1

您不能使用 Moq 来验证您正在从该对象的另一种方法调用该对象的一种方法。您可以做的是验证在您的 Save() 方法中调用的内容是否被调用。

例如,如果我正在编写自己的存储库并使用 Ado.Net 更新数据库,我可以执行以下操作:

public class MyRepository : IRepository {
   private readonly IDatabase m_db;
   public MyRepository(IDatabase myDatabase){
      m_db = myDatabase;
   }

   public void Register(string email, string password, etc.){
      // ... do stuff ...
      Save(m);
      // ... do stuff ...
   }

   public void Save(Member member){
      // ... build sql query ...
      m_db.ExecuteNonQuery(sqlCommand);

   }
}

然后,您将在测试中将模拟的数据库对象传递给您的存储库,并验证:

[TestMethod]
public void Register_calls_Save_method_when_Member_is_valid()
{
    Mock<IDatabase> _mockDB = new Mock<IDatabase>();
    // Setup mockDB with return values for GetByEmail(), etc.

    _repository = new MyRepository(_mockDB.Object);

    MembershipCreateStatus status = _repository.Register("Email@Email.com", "password", "password");
    _mockDB.Verify(r => r.ExecuteNonQuery(It.IsAny<SqlCommand>()), Times.Once());
}

因此,您不是在验证 Save() 是否被显式调用,而是通过验证是否调用了正确的底层数据库调用,您可以验证 Save() 是否发生。

同样的方法也适用于其他框架。

于 2012-11-09T03:14:21.447 回答