4

質問

インターフェイスを実装するオブジェクトによって計算されたパスワードと等しいメソッドCredentialsを実行した後、特定の資格情報のパスワードを検証するクラスの単体テストを作成したいと考えています。Calculate()IPasswordCalculator

実際、私が作成したモック オブジェクトは、メソッドをstring.Empty呼び出したときにCalculate(ICredentials)、 の代わりに値を返します。これが目的の戻り値にPa$$w0rdなります。

それで...

  • スタブ クラスを手動で作成せずにこのテストを実装するにはどうすればよいですか?
  • モックオブジェクトのコールバックメソッドを常に返すように定義するにはどうすればよいPa$$w0rdですか?

前もって感謝します。

コード

IPasswordCalculator インターフェイス

/// <summary>
///     The password calculator interface.
/// </summary>
public interface IPasswordCalculator
{
    /// <summary>
    /// Calculates the user password using 
    /// <paramref name="credentials"/> instance.
    /// </summary>
    /// <param name="credentials">
    /// <see cref="ICredentials"/> to perform the calculation.
    /// </param>
    void Calculate(ICredentials credentials);
}

ICredentials インターフェイス

/// <summary>
///     The Credentials interface.
/// </summary>
public interface ICredentials
{
    /// <summary>
    ///     Gets or sets the user password.
    /// </summary>
    string Password { get; set; }

    /// <summary>
    ///     Gets the user name.
    /// </summary>
    string Username { get; }

    /// <summary>
    ///     Calculates the password.
    /// </summary>
    void Calculate();
}

資格情報の実装

/// <summary>
///     User credentials.
/// </summary>
public sealed class Credentials : ICredentials
{
    /// <summary>
    ///     Initializes a new instance of the <see cref="Credentials" /> class.
    /// </summary>
    /// <param name="passwordCalculator">
    ///     The credentials calculator.
    /// </param>
    /// <param name="username">
    ///     The user name.
    /// </param>
    public Credentials(IPasswordCalculator passwordCalculator, string username)
    {
        this.Calculator = passwordCalculator;
        this.Username = username;
        this.Password = string.Empty;
    }

    /// <summary>
    ///     Calculates the password.
    /// </summary>
    public void Calculate()
    {
        if (null != this.Calculator)
        {
            this.Calculator.Calculate(this);
        }
    }
}

テスト

    /// <summary>
    /// Calculate should set password value expected using calculator.
    /// </summary>
    [TestMethod]
    public void CalculateShouldSetPasswordValueExpectedUsingCalculator()
    {
        ICredentials credentials = null;
        var repo = new MockRepository(MockBehavior.Default);
        var mock = repo.Create<IPasswordCalculator>();
        mock.Setup(x => x.Calculate(credentials))
            .Callback(() => { credentials.Password = "Pa$$w0rd"; });

        IPasswordCalculator calculator = mock.Object;

        credentials = new Credentials(calculator, "Me");
        credentials.Calculate();

        Assert.AreEqual("Pa$$w0rd", credentials.Password);  // Fail
    }
4

2 に答える 2

5

次の方法でモックをセットアップする必要があります

mock.Setup(x => x.Calculate(It.IsAny<ICredentials>()))
    .Callback((ICredentials c) => { c.Password = "Pa$$w0rd"; });

したがって、「メソッドICredentialsのパラメーターとして取得するものは何でも、それを 'Pa$$word'に設定してください」と伝えます。CalculatePassword

于 2013-11-06T12:24:45.043 に答える
0

mock.Setup() を呼び出す前に、資格情報変数を初期化する必要があると思います。あなたのコードでは、Moq は credentials.Calculate(null) の呼び出しを期待しています。

于 2013-11-06T12:24:43.293 に答える