49

私はMoqのドキュメントを見てきましたが、コメントが短すぎて、それができることのそれぞれを理解できません。

私が得られない最初のことはIt.IsAny<string>(). //example using string

値を入れるだけでなく、これを使用する利点はありますか? 値を気にしないならこれを使えと言う人がいるのは知っていますが、値を気にしないなら、単に「a」か何かをすることはできませんか? これは、より多くのタイピングのように思えます。

第二に、値を気にしない場合の例はいつですか? 私は、Moq が一致する値を必要とすると考えました。

It.Is<>目的も使い方も全くわかりません。例とそれが何を示そうとしているのかわからない。

Times次に、いつ使用するか(およびそのAtMostメソッドなど)がわかりません。何かをセットアップする回数を制限するのはなぜですか? 2 回使用する必要があるAppConfig値があります。たとえば、一度に制限したいのはなぜですか?これは、テストが失敗するだけです。これは、他の人があなたのコードや何かに別のものを追加するのを止めるためですか?

使い方がわかりませんmock.SetupAllProperties(); プロパティを設定するものは何ですか?

また、プロパティを設定する方法が非常に多くある理由と、それらの違いが何であるかもわかりません。ドキュメントには次のものがあります。

SetupGet(of property)
SetupGet<TProperty>

Moq の多くのものが表示されていることに気付きました()-<>それらの違いは何ですか?また、使用中はどのように見えるでしょうか?

彼らが持っている理由もわかりませんSetupGetSetupSetプロパティの設定に 使用しませんか? SetupSetには、ドキュメントで使用する 5 つの異なる方法があります。さらに、と呼ばれる別のものSetupProperty。だからなんでこんなに多いのかわからない。

余談ですが、ラムダで使用される変数が他のラムダから独立しているかどうか疑問に思っています。例えば:

mock.setup(m => m.Test);
stop.setup(m => m.Test);

これで問題ないでしょうか、それとも変数間に競合がありますmか?

最後に、このビデオを見ていましたが、Visual Studio が表示されているかどうか疑問に思っています。彼のインテリセンスは違うように見えます。彼のために電球がポップアップし (netbeans のつらい思い出がよみがえるので、私はそうではありません)、1 つの開き括弧から閉じ括弧などに至る行があります。

4

2 に答える 2

113

It.IsAny / It.Is

これらは、テスト対象のコード内で新しい参照型を渡すときに役立ちます。たとえば、次のようなメソッドがあるとします。

public void CreatePerson(string name, int age) {
    Person person = new Person(name, age);
    _personRepository.Add(person);
}

リポジトリで add メソッドが呼び出されたことを確認したい場合があります。

[Test]
public void Create_Person_Calls_Add_On_Repository () {
    Mock<IPersonRepository> mockRepository = new Mock<IPersonRepository>();
    PersonManager manager = new PersonManager(mockRepository.Object);
    manager.CreatePerson("Bob", 12);
    mockRepository.Verify(p => p.Add(It.IsAny<Person>()));
}

このテストをより明確にしたい場合は、人物オブジェクトが一致しなければならない述語を提供することで It.Is を使用できます。

[Test]
public void Create_Person_Calls_Add_On_Repository () {
    Mock<IPersonRepository> mockRepository = new Mock<IPersonRepository>();
    PersonManager manager = new PersonManager(mockRepository.Object);
    manager.CreatePerson("Bob", 12);
    mockRepository.Verify(pr => pr.Add(It.Is<Person>(p => p.Age == 12)));
}

このようにして、 add メソッドを呼び出すために使用された person オブジェクトの age プロパティが に設定されていない場合、テストは例外を通過します12

タイムズ

次のような方法がある場合:-

public void PayPensionContribution(Person person) {
    if (person.Age > 65 || person.Age < 18) return;
    //Do some complex logic
    _pensionService.Pay(500M);
}

テストしたいことの 1 つは、65 歳以上の人がメソッドに渡されたときに、pay メソッドが呼び出されないことです。

[Test]
public void Someone_over_65_does_not_pay_a_pension_contribution() {
    Mock<IPensionService> mockPensionService = new Mock<IPensionService>();
    Person p = new Person("test", 66);
    PensionCalculator calc = new PensionCalculator(mockPensionService.Object);
    calc.PayPensionContribution(p);
    mockPensionService.Verify(ps => ps.Pay(It.IsAny<decimal>()), Times.Never());
}

同様に、コレクションを繰り返し処理し、コレクション内の各アイテムのメソッドを呼び出す状況を想像することができます。特定の回数だけ呼び出されていることを確認したい場合と、そうでない場合があります。お手入れ。

SetupGet / SetupSet

これらの人について注意する必要があるのは、モックの設定方法ではなく、コードがモックと対話する方法を反映していることです。

public static void SetAuditProperties(IAuditable auditable) {
    auditable.ModifiedBy = Thread.CurrentPrincipal.Identity.Name;
}

この場合、コードは IAuditable インスタンスの ModifiedBy プロパティを設定し、IPrincipal の現在のインスタンスの Name プロパティを取得しています。

[Test]
public void Accesses_Name_Of_Current_Principal_When_Setting_ModifiedBy() {
    Mock<IPrincipal> mockPrincipal = new Mock<IPrincipal>();
    Mock<IAuditable> mockAuditable = new Mock<IAuditable>();

    mockPrincipal.SetupGet(p => p.Identity.Name).Returns("test");

    Thread.CurrentPrincipal = mockPrincipal.Object;
    AuditManager.SetAuditProperties(mockAuditable.Object);

    mockPrincipal.VerifyGet(p => p.Identity.Name);
    mockAuditable.VerifySet(a => a.ModifiedBy = "test");
}

この場合、IPrincipal のモックに name プロパティを設定しているため、プロパティ自体を設定していない Identity の Name プロパティで getter が呼び出されたときに "test" が返されます。

SetupProperty / SetupAllProperties

上記のテストを読むように変更された場合を見てください

[Test]
public void Accesses_Name_Of_Current_Principal_When_Setting_ModifiedBy() {
    Mock<IPrincipal> mockPrincipal = new Mock<IPrincipal>();
    Mock<IAuditable> mockAuditable = new Mock<IAuditable>();
    mockPrincipal.SetupGet(p => p.Identity.Name).Returns("test");

    var auditable = mockAuditable.Object;

    Thread.CurrentPrincipal = mockPrincipal.Object;
    AuditManager.SetAuditProperties(auditable);

    Assert.AreEqual("test", auditable.ModifiedBy);
}

テストは失敗します。これは、指定しない限り、Moq によって作成されたプロキシがプロパティの set メソッドで実際に何もしないためです。実際、モック オブジェクトは次のようになります。

public class AuditableMock : IAuditable {
     public string ModifiedBy { get { return null; } set { } }

} 

テストに合格するには、Moq にプロパティを設定して標準のプロパティ動作を持たせる必要があります。SetupProperty を呼び出すことでこれを行うことができ、モックは次のようになります。

public class AuditableMock : IAuditable {
     public string ModifiedBy { get; set; }
} 

上記のテストは、値「test」がモックに対して保存されるため、合格します。複雑なオブジェクトをモックする場合、すべてのプロパティに対してこれを実行したい場合があるため、 SetupAllProperties ショートカット

最後に、IDE の電球は ReSharper プラグインです。

于 2009-07-03T20:47:04.423 に答える
5

プロパティの正確な値を気にしない場合は、正確な値が重要ではないという事実を明示しているため、.IsAnyを使用することをお勧めします。「abc」としてハードコーディングした場合、テストしているコードが「a」で始まるか「c」で終わるか、3文字の長さであるかなどに依存するかどうかは明確ではありません。

于 2009-07-02T14:26:02.867 に答える