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を使用して、オブジェクトの1つのメソッドを、そのオブジェクトの別のメソッドから呼び出していることを確認することはできません。できることは、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 に答える