ASP.NET Core 1.0(MVC 6)プロジェクトでは、Response
プロパティを使用してヘッダーを設定するControllerアクションメソッドがあります。
[HttpGet]
public IActionResult Get()
{
...
Response.Headers.Add("Location", location);
...
}
このアクションメソッドの単体テストを実装しようとしましたが、Response
プロパティの値がnullです。
Response
プロパティにはセッターがあり、単体テスト中にその値を新しいHttpResponse
インスタンスに設定できるため、これは以前のバージョンのASP.NETでは簡単に解決できました。
ただし、ASP.NET 5では、Response
にはセッターがなく、ゲッターのみがあります。
単体テストでResponse
の値を設定するにはどうすればよいですか?
[〜#〜] update [〜#〜]:明確にするために:この質問はASP.NET Core 1.についてです。重複としてリンクされているもう1つの質問は、ASP.NET 4に関するものであり、その後Apiが変更されたため、そこでの回答はこの質問には適用されません。
この問題の解決策を1つ見つけましたが、それは少し面倒で複雑なので、もっと簡単なアプローチがあれば、それでも興味があります。
Controller
は、そのResponse
プロパティの値をActionContext.HttpContext
から取得します。これをモックするのが難しいのは、これらのプロパティがすべて読み取り専用であるため、単にモック値を設定するだけではなく、プレイ中のすべてのオブジェクトに対してモックを作成する必要があることです。
テストで必要な応答の一部はHeaders
コレクションだったので、次のモックを作成して使用し、それを利用できるようにする必要がありました。 (モックは Moq で行われます。)
var sut = new MyController();
// The HeaderDictionary is needed for adding HTTP headers to the response.
// This needs a couple of different Mocks, because many properties in the class model are read-only.
var headerDictionary = new HeaderDictionary();
var response = new Mock<HttpResponse>();
response.SetupGet(r => r.Headers).Returns(headerDictionary);
var httpContext = new Mock<HttpContext>();
httpContext.SetupGet(a => a.Response).Returns(response.Object);
sut.ActionContext = new ActionContext()
{
HttpContext = httpContext.Object
};
これは、単一のプロパティをモックするために見たいコードよりも少し多いコードですが、これ以上のアプローチはまだ見つかりませんでした。うまく機能しているようです。
ResponseWrapperを仮想プロパティで使用でき、それをモックして、「Location」パラメーターを使用した仮想AddHeaderメソッドの呼び出しを1回期待できます。 関連する質問ここで: MOQ-MVCコントローラーのResponse.Cookies.Clear()をモックする
これらの例を確認できます:ASP.Net 5 MVC 6の場合:
NancyFx( http://nancyfx.org/ )( https://github.com/NancyFx/Nancy )を試してみたい場合の別のオプションは非常に簡単です:- https://github.com/NancyFx/Nancy/wiki/Testing-your-application
たとえば、ログインページをテストしていて、ユーザーが誤った資格情報を入力した場合にユーザーが「エラー」ページにリダイレクトされたことを確認したい場合は、ShouldHaveRedirectedToアサーションを使用できます。
[Fact] public void Should_redirect_to_login_with_error_details_incorrect() { // Given var bootstrapper = new DefaultNancyBootstrapper(); var browser = new Browser(bootstrapper); // When var response = browser.Post("/login/", (with) => { with.HttpRequest(); with.FormValue("Username", "username"); with.FormValue("Password", "wrongpassword"); }); // Then response.ShouldHaveRedirectedTo("/login?error=true&username=username");
}
もっとある:
[Fact] public void Should_display_error_message_when_error_passed() { // Given var bootstrapper = new DefaultNancyBootstrapper(); var browser = new Browser(bootstrapper); // When var response = browser.Get("/login", (with) => { with.HttpRequest(); with.Query("error", "true"); }); // Then response.Body["#errorBox"] .ShouldExistOnce() .And.ShouldBeOfClass("floatingError") .And.ShouldContain( "invalid", StringComparison.InvariantCultureIgnoreCase); }