3

新しいRhinoMocks3.5 Arrange / Act / Assert(AAA)テストスタイルを使用すると、テストの作成に問題が発生します。

リポジトリクラスのメソッドを呼び出すメソッドがあります。ActivateFoo。FooオブジェクトにはIsActiveプロパティがあります。ActivateFooオブジェクトの結果により、プロパティが変更されます。

サンプルコードは次のとおりです。

[TestMethod]
public void Should_update_foo_to_active_inside_of_repository()
{
  // arrange
  var repo = MockRepository.GenerateMock<IRepository>();
  var foo = new Foo() { ID = 1, IsActive = false };
  var target = new Presenter(repo);
  repo.Expect(x => x.ActivateFoo(foo)).Return(true);

  // act
  target.Activate(foo);

  // assert
  Assert.IsTrue(foo.IsActive);
  repo.VerifyAllExpectations();  
}

コードの重要な部分は「ActivateFoo(foo))」の間にあると思います。および「Return(true);」。

メソッドチェーンが舞台裏でどのように機能するかを明確にするための1つのポイント、期待する行にコードが記述されている場合、それがReturn()の後か前かは重要ですか?(もちろん、ソリューションがExpectのMethodOptionsオーバーロードなどを使用している場合を除きます)。

助けてくれてありがとう。

4

4 に答える 4

1

AB Kolan のおかげで、これは私が使用して動作する結果のコードです。

[TestMethod]
public void Should_update_foo_to_active_inside_of_repository()
{
    // arrange
    var repo = MockRepository.GenerateMock<IRepository>();
    var foo = new Foo() { ID = 1, IsActive = false };
    var target = new Presenter(repo);
    repo.Expect(x => x.ActivateFoo(foo)).
        Do(new Func<Foo, bool>(
            delegate(Foo f) { f.IsActive = true; return true; }
        ));

    // act
    target.Activate(foo);

    // assert
    Assert.IsTrue(foo.IsActive);
    repo.VerifyAllExpectations();
}

私は、可能であればインライン デリゲートを好み、テストを 1 回使用するために余分な関数メソッドを持たなければならないことを好まない傾向があります。

問題に対処するために、これは私がやるべきことなのか、デザインに関してはやらないべきなのか. 名前があるので、これは正確なコードではなく、target.Activate() メソッドの内部です。Activate() 内のコードはいくつかのチェックを行い、必要に応じてリポジトリの ActivateFoo() を実行し、その操作の結果をチェックして他のことを行います。

そのため、後でこれをリファクタリングしてステップを分離する必要がある可能性がありますが、今のところ、機能するようになりました。

ありがとう

于 2009-03-11T18:52:49.987 に答える
0

私はまだこのバージョンのRhinoMocksを使用していませんでしたが、古いバージョンでは、フラグを設定して値を返すために.Do(適切なデリゲート)を使用する必要がありました(.Returnの代わりに)。

うまくいくかどうか教えてください。うまくいかない場合は、試してみることができます。

于 2009-03-11T17:40:11.673 に答える
0

Do ハンドラーを使用して、このようなことを試してみてください。正直なところ、ActivateFoo は void 戻り型であるべきだと思います。しかし、ここに bool 戻り型の ActivateFoo のコードがあります。

    [TestMethod]
    public void Should_update_foo_to_active_inside_of_repository()
    {
        // arrange
        var repo = MockRepository.GenerateMock<IRepository>();
        var foo = new Foo() { ID = 1, IsActive = false };
        var target = new Presenter(repo);
        repo.Expect(x => x.ActivateFoo(foo)).
            Do(new ActivateFooDelegate(ActivateFooDelegateInstance));
        // act
        target.Activate(foo);

        // assert
        Assert.IsTrue(foo.IsActive);
        repo.VerifyAllExpectations();
    }

    private delegate bool ActivateFooDelegate(Foo f);

    public bool ActivateFooDelegateInstance(Foo f)
    {
        f.IsActive = true;
        return f.IsActive;
    }
于 2009-03-11T18:01:12.687 に答える
0

見た目からすると、ActivateFoo は void メソッドである必要があります。そして、あなたはそれを嘲笑しているので、それがあなたのオブジェクトの何かを変更することを確認すべきではありません.

プレゼンターで Activate メソッドをテストするときではなく、リポジトリ メソッド ActivateFoo をテストするときに IsActive プロパティが変更されていることを確認します。

于 2009-03-11T17:56:46.783 に答える