18

C# と Moq で単体テストを行う方法を学ぼうとしており、小さなテスト状況を構築しました。このコードを考えると:

public interface IUser
{

    int CalculateAge();
    DateTime DateOfBirth { get; set; }
    string Name { get; set; }
}

public class User : IUser
{
    public DateTime DateOfBirth { get; set; }
    string Name { get; set; }

    public int CalculateAge()
    {
        return DateTime.Now.Year - DateOfBirth.Year;
    }
}

メソッドをテストしたいCalculateAge()DateOfBirthこれを行うには、テスト メソッドで次のようにして、プロパティに既定値を指定する必要があると考えました。

var userMock = new Mock<IUser>();
userMock.SetupProperty(u => u.DateOfBirth, new DateTime(1990, 3, 25)); //Is this supposed to give a default value for the property DateOfBirth ?
Assert.AreEqual(22, userMock.Object.CalculateAge());

しかし、アサーションになると、 の値CalculateAge()は 0 に等しくなりますが、 はDateOfBirthに等しくなりnew DateTime(1990, 3, 25)ます。

これはばかげた例のように見えるかもしれませんが、何でも...モックを使用して、オブジェクト内のまだ開発されていないメソッド/プロパティに値を与えることができると思ったので、メソッドのテストは別のコンポーネントに依存しません私のクラスの、または私のオブジェクトのデフォルトのコンテキストを設定することさえあります(したがって、ここではユーザーの名前です...)私はこの問題に間違った方法で取り組んでいますか?

ありがとう。

4

2 に答える 2

23

はい、あなたは間違ったアプローチをしていますが、心配しないでください。理由を説明します。最初のヒントは

Userクラスを完全に削除すると、すべてが同じになります。

あなたがしているとき:

var userMock = new Mock<IUser>();

そのインターフェイスの偽の\モックオブジェクトを作成するだけで、初期クラスとは何の関係もないUserため、ばかげて0を返す偽のものを除いて、メソッドの実装はありません。そのため、CalculateAge0を取得していますあなたのアサートステートメント。

だから、あなたは言っていた:

オブジェクト内のまだ開発されていないメソッド/プロパティに値を与えるためにモッキングを使用できると考えたので、メソッドのテストはクラスの別のコンポーネントに依存しません

IUser の消費者がいるとしましょう。次のように言いましょう。

class ConsumerOfIUser
{
   public int Consume(IUser user)
   {
      return user.CalculateAge() + 10;
   }
}

ConsumerOfIUserその場合、IUser.CalculateAge() が 10 を返したときにどのように動作するかをテストする必要があるため、IUser のモックは完全に理にかなっています。次のようにします。

var userMock = new Mock<IUser>();
userMock.Setup(u => u.CalculateAge()).Returns(10);

var consumer = new ConsumerOfIUser();
var result = consumer.Consume(userMock);

Assert.AreEqual(result, 20); //should be true
于 2012-05-25T19:21:38.147 に答える
2

何をテストしようとしているかによって異なります。この場合、User オブジェクトをモック化したので、このクラスをモック オブジェクトに置き換えているため、このクラス内で何かをテストしても意味がありません。User オブジェクトをテストしたい場合は、モックアウトしないでください。

モックは、テストしたくない依存オブジェクトを置き換えるために使用されます。たとえば、文字列の代わりに Name オブジェクト (たとえば、名、姓、役職などを含む) があり、Name オブジェクトをテストしたくない場合、User オブジェクトだけをテストするには、次のモックを作成します。 User オブジェクトを作成するときに使用する Name オブジェクト。

于 2012-05-25T19:22:22.077 に答える