【C# / ASP.NET WebForm】HttpRequestBase を継承しMock クラスを作成し、HttpRequest をテストする
前置き
現場の案件で、外部APIやDB接続が絡んだ少々複雑な判定でCookie を作成するという処理を実装することになり、
対象の処理でユニットテストを作成しておきたくなりました。
Cookie の作成や、作成した値を検証するには当然ですがHttpRequest
やHttpResponse
のインスタンスが必要ですが、
これらのクラスのインスタンスをユニットテストで生成するのは困難(ほぼ不可能のはず)です。
そこで、ASP.NET ではHttpRequestWrapper
というクラスが実装されています。
HttpRequestWrapper
はHttpRequestBase
という抽象クラスから派生されています。
HttpRequestBase
はHttpRequest
と同じプロパティ、関数を保有したクラスです。
対象となる処理の実装ではHttpRequestBase
を使用し、
HttpRequestWrapper
でHttpRequest
をラップしたインスタンスを使用することにします。
これらはHttpResponse
でも同様です。
文章だとややこしいので、サンプルコードを実装してみました。
Controller(HttpRequestBase, HttpResponseBaseを使用する処理)
public class IndexController { public IndexController() { } public void createCookie(HttpRequestBase request, HttpResponseBase response) { if (request.QueryString == null) { throw new ArgumentNullException(); } string value = request.QueryString["hoge"]; var cookie = new HttpCookie("hoge"); cookie.Value = "hoge" + value; response.Cookies.Add(cookie); } }
aspx.cs
public partial class Index : System.Web.UI.Page { private readonly IndexController _controller = new IndexController(); protected void Page_Load(object sender, EventArgs e) { _controller.createCookie(new HttpRequestWrapper(Request), new HttpResponseWrapper(Response)); } }
そして、ユニットテストコードでは以下のようにHttpRequestBase
から派生したMockクラスを作成し、
テストで必要となるプロパティや関数をOverrideして実装します。
Mockクラス
public class HttpRequestMock : HttpRequestBase { private readonly NameValueCollection _queryString; public HttpRequestMock(NameValueCollection queryString) { _queryString = queryString; } public override NameValueCollection QueryString => _queryString; } public class HttpResponseMock : HttpResponseBase { private readonly HttpCookieCollection _cookies = new HttpCookieCollection(); public override HttpCookieCollection Cookies => _cookies; }
テストコード
[TestMethod] public void createCookieNormalCase() { // Arrange var requestMock = new HttpRequestMock(new NameValueCollection() { { "hoge", "12345" } }); var responseMock = new HttpResponseMock(); var sut = new IndexController(); // Act sut.createCookie(requestMock, responseMock); // Assert Assert.AreEqual("hoge12345", responseMock.Cookies["hoge"].Value); }
サンプルコード
今回の記事で作成したサンプルコードをGitHubにアップしました。