12

私は RhinoMocks が初めてで、内部で何が起こっているかに加えて、構文を把握しようとしています。

ユーザー オブジェクトがあります。これを User と呼びます。これには、IsAdministrator というプロパティがあります。IsAdministrator の値は、ユーザーのセキュリティ権限をチェックする別のクラスを介して評価され、それらの権限に基づいて true または false を返します。この User クラスをモックして、IsAdministrator の戻り値を偽造して、いくつかの単体テストを分離しようとしています。

これは私がこれまで行っていることです:

public void CreateSomethingIfUserHasAdminPermissions()
{
    User user = _mocks.StrictMock<User>();
    SetupResult.For(user.IsAdministrator).Return(true);

    // do something with my User object
} 

ここで、Rhino がプロパティ ゲッターへの呼び出しを「偽装」し、true を返すことを期待しています。これは間違っていますか?現在、IsAdministrator プロパティの依存関係が原因で例外が発生しています。

ここで私の目標を達成する方法を誰かが説明できますか?

4

3 に答える 3

11

これに飛び込む前に、1 つ簡単な注意事項があります。通常、「Strict」モックの使用は避けたいと考えます。これは、脆弱なテストになるためです。厳密なモックは、Rhino に明示的に通知していないことが発生した場合に例外をスローします。また、モックを作成するために呼び出しを行うときに、Rhino が何をしているのか正確に誤解していると思います。定義した System.Type から派生したか、実装したカスタム オブジェクトと考えてください。自分でやった場合は、次のようになります。

public class FakeUserType: User
{
    //overriding code here
}

IsAdministrator はおそらく User 型の単なるパブリック プロパティであるため、継承型でオーバーライドすることはできません。

あなたの質問に関する限り、これを処理する方法は複数あります。aaronjensenが次のように述べているように、 IsAdministratorをユーザー クラスの仮想プロパティとして実装できます。

public class User
{
    public virtual Boolean IsAdministrator { get; set; }
}

これは良い方法ですが、 User クラスから継承する予定がある場合に限ります。また、このクラスの他のメンバーを偽造したくない場合は、それらも仮想にする必要がありますが、これはおそらく望ましい動作ではありません。

これを実現するもう 1 つの方法は、インターフェイスを使用することです。モックしたいのが本当に User クラスである場合は、そこからインターフェイスを抽出します。上記の例は次のようになります。

public interface IUser
{
    Boolean IsAdministrator { get; }
}

public class User : IUser
{
    private UserSecurity _userSecurity = new UserSecurity();

    public Boolean IsAdministrator
    {
        get { return _userSecurity.HasAccess("AdminPermissions"); }
    }
}

public void CreateSomethingIfUserHasAdminPermissions()
{
    IUser user = _mocks.StrictMock<IUser>();
    SetupResult.For(user.IsAdministrator).Return(true);

    // do something with my User object
}

必要に応じて、依存性注入と IOCを使用してより洗練されたものにすることができますが、基本原則は全面的に同じです。通常、クラスは具体的な実装ではなくインターフェイスに依存する必要があります。

これが役立つことを願っています。私は主要なプロジェクトで長い間 RhinoMocks を使用してきたので、TDD とモックについて質問することを躊躇しないでください。

于 2008-09-17T03:41:00.480 に答える
1

IsAdministratorが仮想であることを確認してください。

また、必ず_mocks.ReplayAll()を呼び出してください

于 2008-09-16T23:46:38.297 に答える
0

_mocks.ReplayAll() は何もしません。カウントされない SetupResult.For() を使用しているからです。コードがすべて正しく動作することを確認するには、Expect.Call() を使用します。

于 2010-04-08T08:52:24.493 に答える