2013-03-07 149 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 ...