4

Ninjectを使用してWebAPIプロジェクトを設定し、最新バージョンのWeb APIで動作させるために、ここで詳しく説明する修正を使用しました。すべてが正常に機能していますが、現在、いくつかのテストを作成しようとしています。

ここで詳しく説明するように、メモリ内ホスティングを使用してテスト用のプロジェクトを実行しています。DelegatingHandlerこれは、認証を実行し、すべてのApiコントローラーで使用される要求メッセージにプロパティを設定するためです。

したがって、テスト用の基本クラスがあり、作業中のNinjectコードからほとんど取得した構成と構成SetUpをセットアップするメソッドがHttpServerあります。

[SetUp]
public void Setup()
{
    bootstrapper = new Bootstrapper();

    DynamicModuleUtility.RegisterModule(
        typeof(OnePerRequestHttpModule));

    DynamicModuleUtility.RegisterModule(
        typeof(NinjectHttpModule));

    bootstrapper.Initialize(CreateKernel);

    var config = new HttpConfiguration();
    config.Routes.MapHttpRoute("Login",
        "api/auth/token",
        new { controller = "Users", action = "Login" });

    config.IncludeErrorDetailPolicy =
        IncludeErrorDetailPolicy.Always;

    config.DependencyResolver = 
        new NinjectResolver(CreateKernel());

    config.MessageHandlers.Add(
        new AuthenticationHandler(CreateUserManager()));

    Server = new HttpServer(config);
}

これが私が作成する方法ですMoqMockingKernel

private static IKernel CreateKernel()
{
    var kernel = new MoqMockingKernel();
    kernel.Bind<Func<IKernel>>()
        .ToMethod(ctx => () => new Bootstrapper().Kernel);
    kernel.Bind<IHttpModule>()
        .To<HttpApplicationInitializationHttpModule>();

    RegisterServices(kernel);

    GlobalConfiguration.Configuration.DependencyResolver = 
        new NinjectResolver(kernel);

    return kernel;
}

そして、これは私が使用するオブジェクトを登録する方法です:

private static void RegisterServices(IKernel kernel)
{
    kernel.Bind<IUserManager>().ToMock();

    kernel.Bind<UsersController>().ToSelf();
}

私はコントローラー自体をテストしていませんが、コントローラーの適切なインスタンスを呼び出したいので、ToSelfにバインドしています。私はこれが正しいと仮定していることを認めなければなりません。これはテストの例です:

public void UserCannotLogin()
{
    System.Net.Http.HttpClient client = 
        new System.Net.Http.HttpClient(Server);

    string json = string.Format(
        "{{ \"Username\": \"{0}\", \"Password\": \"{1}\" }}", 
        "wrong", "wrong");

    HttpRequestMessage request = 
        CreateRequest(@"api/auth/token", json, HttpMethod.Get);

    Action action = () => client.SendAsync(request);

    using (var response = client.SendAsync(request).Result)
    {
        response.StatusCode.Should()
            .Be(HttpStatusCode.Unauthorized);
    }
}

基本的に404エラーが発生します。私がそれをデバッグするとき、それは私のに行きますDelegatingHandler、しかしそれは私のコントローラーに行きません。

私はここで根本的にポイントを逃しているように感じます、そして私がやろうとしていることをすることさえできないかもしれません、しかし誰かがこれをする方法または達成するための別の方法のいずれかについて何か提案があれば同じこと、私はすべての耳です。

更新MockingKernel特に指定がない限り、のデフォルトの動作はモックを提供することであるためだと思います。そのため、のモックが返されIHttpControllerSelectorます。私は今、いくつかのデフォルトのものを設定しました:

kernel.Bind<IHttpControllerSelector>()
    .To<DefaultHttpControllerSelector>();
kernel.Bind<IContentNegotiator>()
    .To<DefaultContentNegotiator>();

フォーマッターが指定されていないため、まだ機能していないと思います。私は明日それを試して、それが私をそこに連れて行くかどうか確かめます。

4

1 に答える 1

1

さて、ここで根本的にポイントが欠けていると言ったときは正しかったと思いますが、他の誰かが同じ間違いを避けるのに役立つ場合に備えて、これに答えます!

NinjectMockingKernelは、主に自動モックに関するものだと思います。そのため、テストでの設定方法を気にしないインターフェイスがたくさんある場合は、テストでそれらを無視して、自動的に作成されます。君。

Web APIの場合、コントローラーセレクタークラスを自動モックしたくないので、これは間違いなく当てはまりません。そうしないと、コントローラーを呼び出すことになりません。

したがって、私が思いついた解決策は、標準のNinjectを使用しKernel続けてから、インターフェイスを一定のモックオブジェクトにバインドすることです。

kernel.Bind<IUserManager>().ToConstant(CreateUserManager());

private IUserManager CreateUserManager()
{
    Mock<IUserManager> userManager = new Mock<IUserManager>();

    // Set up the methods you want mocked

    return userManager.Object;
}

これを行うことで、HttpClientを使用してメモリ内のHttpServerを呼び出し、正常に呼び出してDelegatingHandlerからコントローラーに到達するテストを正常に作成することができました。

于 2012-08-14T10:38:32.850 に答える