3

私が見る限り、TestMethod からコントローラー インスタンスを作成するときに、mvc4 アプリが Windows 認証を使用しない限り (そして、コントローラーがユーザー オブジェクトを読み取ろうとする場合)、ユーザー オブジェクトは null のままです。だから私のテストは失敗します。それらを機能させるにはどうすればよいですか?

追加情報: これは私のテストです:

[TestMethod]
public void Create()
{
   var ctrl = new LanguageController();
   var res = ctrl.Manage() as ViewResult;
   Assert.IsNotNull(res);
   Assert.AreEqual(res.ViewName, "Create");
}

そして、私の LanguageController には基本クラスがあります:

public class LanguageController : MyController
{

これにはコンストラクターがあり、その中に外部の権限マネージャーによってユーザー権限を発見しようとします。

public class MyController : Controller
  {
     protected Rights rm;
     public MyController()
     {
        this.rm = RightManager.Discover(User.Identity);
     }

このコンストラクターでは、ユーザーが null であることがわかります。

4

1 に答える 1

2

さて、あなたの単体テストにはいくつかの問題があります。ユーザーが null である理由を説明しながら、問題を解決していきます。

これは、User (IPrincipal) インスタンスのスタブ バージョンを提供していないためです。そのため、それをコントローラーに注入する方法を見つける必要があります。Controller 内の多くの依存関係を外部化することが重要です。そうすることで、動作するクリーンな Controller を提供するのではなく、重要なことにtestabilityを促進することができます。

以下のように依存関係を挿入します。

SUT (テスト対象のシステム)

public class MyController : Controller
{
    protected Rights rm;
    public MyController(IPrincipal user, IRightManager rightManager)
    {
        this.rm = rightManager.Discover(user.Identity);
    }
}

public class LanguageController : MyController
{
    public LanguageController(IPrincipal user, IRightManager rightManager)
        : base(user, rightManager)
    { 
    }

    public ActionResult Manage()
    {
        return View("Manage");
    }
}

これにより、偽の User と偽の Right Manager を挿入することができます。

では、実行時にアプリケーションを実行するときに、実際のユーザーである RightManager を取得するにはどうすればよいでしょうか?

コントローラーの作成中に、依存関係をコントローラーに注入できます。

依存性注入フレームワークを使用しない場合(理想的には使用する必要があります)、手動で依存性を注入することができます。たとえば、コントローラーでプロパティを作成し、コントローラーに実際のインスタンスを注入し、単体テスト中に偽のインスタンスを注入するなどです。少し逸脱しているため、詳細には触れませんが、多くの SO を見つけることができますこの側面に関する質問/ウェブ参照。

単体テスト これで依存関係を注入する方法ができました。単体テストから簡単に注入できます。分離フレームワーク(AKA およびモック オブジェクト フレームワーク)を使用するか、古い学校の方法 (手書きのモック/偽物/スタブ) としてそれらを注入することができます。分離フレームワークを使用することをお勧めします。手動の偽物を作成すると、不要なコードの複製とメンテナンスの問題が発生します。あなたがどのフレームワークを好むかわからないので、手書きのフェイク/モック/スタブをいくつか作成しました。

public class FakeRightManager : IRightManager {
    public Rights Discover(IIdentity identity) {
        return new Rights();
    }
}

public class MyFakeIdentity : IIdentity {
    public string AuthenticationType {
        get { throw new NotImplementedException(); }
    }

    public bool IsAuthenticated {
        get { throw new NotImplementedException(); }
    }

    public string Name {
        get { throw new NotImplementedException(); }
    }
}

public class MyFakePrincipal : IPrincipal {
    public IIdentity Identity {
        get { return new MyFakeIdentity(); }
    }

    public bool IsInRole(string role) {
        throw new NotImplementedException();
    }
}

あなたのユニットテスト:

    [TestMethod]
    public void ManageAction_Execute_ReturnsViewNameManager()
    {
        var fakeUser = new MyFakePrincipal();
        var fakeRightManager = new FakeRightManager();
        var ctrl = new LanguageController(fakeUser, fakeRightManager);

        var res = ctrl.Manage() as ViewResult;

        Assert.AreEqual<string>(res.ViewName, "Manage");
    } 

テストでは、Assert.IsNotNull(res); をチェックします。res がnullの場合、2番目のアサートがとにかく失敗するため、これは必要ありません。

また、常に非常にわかりやすい正確な単体テスト名を付けてください。あなたが正確にテストしたものを反映してください。テストの可読性と保守性が向上します。

于 2013-10-29T10:19:02.077 に答える