2016-10-30 7 views
1

私のコントローラのアクションのいくつかは、このメソッドをGenerateActionLinkと呼びます。asp.net MVCのUrlオブジェクトをどうやって模擬するのですか

private string GenerateActionLink(string actionName, string token, string username) 
    { 
     string validationLink = null; 
     if (Request.Url != null) 
     { 
      var encodedToken = EncodedUrlParameter(token); 
      var url = Url.Action(actionName, "Register", new {Token = encodedToken, Username = username}, Request.Url.Scheme); 
      validationLink = url; 
     } 

     return validationLink; 
    } 

これは電子メールで送信される確認リンクを生成するためのものです。それは完全に動作します。私が抱えている問題は、メソッドを呼び出したコントローラアクションをテストするときです。 Urlはnullです。

私はそれを模擬して単体テストでモックを使用できますか?

私はMoqNUnitを使用しています。

注:ActionNameを渡すことができるようにする必要があります。これは、Request.Urlには常に要求が出てくるアクションが一般的なアクションであるため、私はパラメータ値でRequest.Urlをconcatinatingしていません私はリンクにしたい、これは私がアクションリンクを生成するためにUrl.Actionを使用している理由です。

+0

モック 'UrlHelper'をモック、テストを配置する際、コントローラの' Url'プロパティを設定ユニットテストの例です。リクエストを模擬するにはコントローラのhttpコンテキストを疑似し、コントローラコンテキストを設定します。 – Nkosi

答えて

0

これは私の現在の解決策です。私は手動でリンクを構築しました。より良い解決策があれば教えてください。

private string GenerateActionLink(string actionName, string token, string username) 
    { 
     string validationLink = null; 
     if (Request.Url != null) 
     { 
      var encodedToken = EncodedUrlParameter(token); 
      var encodedEmail = EncodedUrlParameter(username); 
      var concatenatedUrl = 
       $"{Request.Url.Scheme}://{Request.Url.Host}/Register/{actionName}?Token={encodedToken}&Username={encodedEmail}"; 
      validationLink = concatenatedUrl; 
     } 

     return validationLink; 
    } 

このように私はまだactionNameを渡すことができます。 Request.Urlを使用する場合、これは常に通常私の質問に記載されているものを使用したいではないアクションがあります。

0

モックUrlHelperを設定し、テストを配置するときにコントローラのUrlプロパティを設定します。リクエストを模擬するにはコントローラのhttpコンテキストを疑似し、コントローラコンテキストを設定します。

ここでは、上記の例に基づいたサンプルコントローラを示します。ここ

public class MyController : Controller { 
    [HttpPost] 
    public ActionResult MyAction() { 
     var link = GenerateActionLink("MyTargetActionName", string.Empty, string.Empty); 

     return View((object)link); 
    } 

    private string GenerateActionLink(string actionName, string token, string username) { 
     string validationLink = null; 
     if (Request.Url != null) { 
      var encodedToken = EncodedUrlParameter(token); 
      var url = Url.Action(actionName, "Register", new { Token = encodedToken, Username = username }, Request.Url.Scheme); 
      validationLink = url; 
     } 

     return validationLink; 
    } 

    private string EncodedUrlParameter(string token) { 
     return "Fake encoding"; 
    } 

} 

は、すべての必要なフレームワークの依存関係

[TestClass] 
public class UrlHelperTest { 
    [TestMethod] 
    public void MockUrlHelper() { 
     //Arrange 
     var requestUrl = new Uri("http://myrequesturl"); 
     var request = Mock.Of<HttpRequestBase>(); 
     var requestMock = Mock.Get(request); 
     requestMock.Setup(m => m.Url).Returns(requestUrl); 

     var httpcontext = Mock.Of<HttpContextBase>(); 
     var httpcontextSetup = Mock.Get(httpcontext); 
     httpcontextSetup.Setup(m => m.Request).Returns(request); 


     var actionName = "MyTargetActionName"; 
     var expectedUrl = "http://myfakeactionurl.com"; 
     var mockUrlHelper = new Mock<UrlHelper>(); 
     mockUrlHelper 
      .Setup(m => m.Action(actionName, "Register", It.IsAny<object>(), It.IsAny<string>())) 
      .Returns(expectedUrl) 
      .Verifiable(); 

     var sut = new MyController(); 
     sut.Url = mockUrlHelper.Object; 
     sut.ControllerContext = new ControllerContext { 
      Controller = sut, 
      HttpContext = httpcontext, 
     }; 

     //Act 
     var result = sut.MyAction(); 

     //Assert 
     mockUrlHelper.Verify(); 
    } 
} 
関連する問題