2013-03-07 154 views
2

我使用起訂量框架編寫單元測試,我有一個返回單元測試模擬Url.Action

return Json(new 
{  
    redirectUrl = Url.Action("Action", "Controller"), 
    isredirection = true 
}); 

我希望能夠在redirectUrl測試結果,但不知道控制器功能如何MockUrl.Action.我如何設置,所以我可以指定如果Url.Action("Action", "Controller")被稱爲返回這個?

+0

通常的做法是包裹在多數民衆贊成注入實例化的包裝靜態類和extensionmethods喜歡這些控制器,然後你可以反過來模擬。 – 2013-03-07 10:08:39

回答

1

你不能。有容易記住嘲弄的規則 - 不能越權,不能模擬 。如果您是從Url類派生的,您能否覆蓋Action方法?不可以。Moq,Rhino,FakeItEasy或任何其他基於DynamicProxy的框架。

你的選擇縮小以下的:

  • 使用不同的框架,而不是基於DynamicProxy(這通常是指基於先進的攔截編譯服務) - 這樣的工具通常支付。與接口/委託
  • 包裝有問題的呼叫,並inject到測試的代碼(這樣你可以嘲笑它採用無框架)

將如何包裝是什麼樣子?

public interface IUrlWrapper 
{ 
    string Action(string name, object values); 
} 

// Wrapper Interface 
public class TestedClass 
{ 
    private readonly IUrlWrapper url; 

    public TestedClass(IUrlWrapper urlWrapper) 
    { 
     this.url = urlWrapper; 
    } 

    // ... 

    return Json(new 
    { 
     redirectUrl = this.url.Action("Action", "Controller"), 
     isredirection = true 
    }); 

    // ... 
} 

通過這樣的設置,您可以使用Moq而不會有其他問題。然而,在單一方法調用就可以一樣好使用Func委託沒有任何隔離框架:

// Func Delegate 
public class TestedClass 
{ 
    private readonly Func<string, object, string> urlAction; 

    public TestedClass(Func<string, object, string> urlAction) 
    { 
     this.urlAction = urlAction; 
    } 

    // ... 

    return Json(new 
    { 
     redirectUrl = this.urlAction("Action", "Controller"), 
     isredirection = true 
    }); 

    // ... 
} 

在您的測試,你只需在飛行創建委託。


我寫了一篇博客文章要多一點進入這個非常細節題:How to mock private method with ...