2

RhinoMocks と Unit Testing は初めてなので、解決策が見つからないように見える問題に遭遇しました (どれだけドキュメントを読んでも)。

問題は次のとおりです。5 つのイベントを公開するインターフェイスを作成しました (ASP.NET のビューと MVP 監視コントローラー パターンに使用されます..... MVC を使用する必要があることはわかっていますが、それはまったく別のことです)。問題)。とにかく、ビューで特定のイベントが発生したときにそれを「IsLoaded」と呼び、プレゼンター内のメソッドが呼び出され、依存性注入を使用して依存関係から値が返され、に設定されることをテストしたいと思います。景色。ここから問題が始まります。Expect.Call(Dependency.GetInfo()).Return(SomeList) を使用すると、Call は実行されません (mock.ReplayAll() メソッドが呼び出されていない場合)。ReplayAll メソッドを呼び出すと、View Interface によって公開される他のイベントへの Presenter オブジェクトによるサブスクリプションのために、ExpectationExceptions が発生します。

したがって、IView.IsLoaded が起動したことをテストするために、IView.ListOfSomething が更新され、Expect.Call() を介して渡したリストと一致することを確認したいと思います。ただし、期待値を設定すると、他のイベント サブスクリプション (プレゼンターのコンストラクターから直接発生する) は、テストの期待値 #0 に失敗します。私が得たのは、view.Save += this.SaveNewList が RhinoMocks ExpectationViolationException を投げたことです。

私の百万ドルの質問は次のとおりです: すべてのイベントに ([セットアップ] を介して) 期待値を設定する必要がありますか?それとも、ユニット テストまたは RhinoMocks のしくみについて、不足している/理解していないものがありますか?

私は単体テストに非常に慣れていないため、RhinoMocks を使用することに注意してください。何を言っているのかわからない場合は、遠慮なく指摘してください。

4

1 に答える 1

2

私は、MVP と rhino のモックも使用したプロジェクトに取り組んでいます。私たちが行ったことは、すべてのテストですべてのイベント サブスクリプションを単純に期待することでした。

    private void SetupDefaultExpectations()
    {
        _mockView.Initializing += null; LastCall.IgnoreArguments();
        _mockView.SavingChanges += null; LastCall.IgnoreArguments();
    }

次に、IMockedObject (RhinoMocks から) に拡張メソッドを構築して、単体テストでイベントをトリガーし、例外をラップ解除して、標準の NUnit の方法で期待できるようにします。

static class IMockedObjectExtension
{
    public static void RaiseEvent(this IMockedObject mockView, string eventName, EventArgs args)
    {
        EventRaiser eventraiser = new EventRaiser(mockView, eventName);

        try
        {
            eventraiser.Raise(mockView, args);
        }
        catch (TargetInvocationException ex)
        {
            throw ex.InnerException;
        }
    }

    public static void RaiseEvent(this IMockedObject mockView, string eventName)
    {
        RaiseEvent(mockView, eventName, EventArgs.Empty);
    }
}

これは、このような単体テストから使用できます

using(_mocks.Record())
{
    Expect.Call(dependency.GetInfo()).Return(someList);
}
using(_mocks.Playback())
{
    Presenter presenter = new Presenter(_mockView, dependency);
    (_mockView as IMockedObject).RaiseEvent("SavingChanges");
}

プレゼンター テスト間の重複を排除するために、これを BasePresenterTest 基本クラスにリファクタリングしました。これは、すべてのプレゼンター テストに対してこの基本構造をセットアップし、ヘルパー メソッドをサブクラスに公開します。

public abstract class BasePresenterTest<VIEW> where VIEW : IBaseView
{
    protected MockRepository _mocks;
    protected VIEW View { get; private set; }

    protected abstract void SetUp();
    protected abstract void TearDown();
    protected abstract void SetupDefaultExpectations();

    [SetUp]
    public virtual void BaseSetUp()
    {
        _mocks = new MockRepository();
        View = _mocks.CreateMock<VIEW>();

        SetUp();
    }

    [TearDown]
    public virtual void BaseTearDown()
    {
        TearDown();

        View = null;
        _mocks = null;
    }

    protected virtual void BaseSetupDefaultExpectations()
    {
        //Setup default expectations that are general for all views
        SetupDefaultExpectations();
    }

    protected virtual IDisposable Record()
    {
        IDisposable mocksRecordState = _mocks.Record();

        BaseSetupDefaultExpectations();

        return mocksRecordState;
    }

    protected virtual IDisposable Playback()
    {
        return _mocks.Playback();
    }

    protected void RaiseEventOnView(string eventName)
    {
        (View as IMockedObject).RaiseEvent(eventName);
    }       
}

これにより、プロジェクトのテストから多くのコードが削除されます。

まだRhinoMocksの古いバージョンを使用していますが、新しいバージョンに移行したら、これを更新しようとします.

于 2008-12-03T14:33:49.307 に答える