2013-03-17 46 views
2

我已经花了更好的另一半今天下午试图找出如何嘲笑(使用MOQ)了相关的点点滴滴单元测试下面的HtmlHelper的UrlHelper类来创建的img标签哪些用户:怎么会一个单元测试的的HtmlHelper实际上采用帮手扩展方法

public static IHtmlString Image(this HtmlHelper helper, string id, string url, string alternateText, object htmlAttributes) 
    { 
     // Instantiate a UrlHelper 
     var urlHelper = new UrlHelper(helper.ViewContext.RequestContext); 

     // Create tag builder 
     var builder = new TagBuilder("img"); 

     // Create valid id 
     builder.GenerateId(id); 

     // Add attributes 
     builder.MergeAttribute("src", urlHelper.Content(url)); 
     builder.MergeAttribute("alt", alternateText); 
     builder.MergeAttributes(new RouteValueDictionary(htmlAttributes)); 

     // Render tag 
     return new MvcHtmlString(builder.ToString(TagRenderMode.SelfClosing)); 
    } 

有没有人在他们的工作已经解决了这个问题?

回答

1

您应该测试的最终结果。如果你知道你应该帮助退还或者拒不像,让说:

<img src="test.jpg" id="testId" alt="something" /> 

那么你的声明应该是通过比较实际结果此字符串。你不应该在乎它是否在内部使用helper。

+0

你不能这样做,因为你建议。你将如何在单元测试中创建HtmlHelper?您无权访问MVC框架的运行时环境,它为您提供了@Html助手属性。你不能只是“新的一个”。你不能只是静态地调用这个方法,因为它是一个使用它所扩展的对象的扩展方法。但是,谢谢你的建议。 – onefootswill 2013-03-17 06:59:52

+0

@onefootswill,你的问题是你的代码中的UrlHelper。有了这门课你就不能做测试。你应该做的是当你将它传递给你的助手而不是你的助手内部时生成URL。 – 2013-03-19 06:56:10

+0

我认为你是对的。虽然我喜欢在扩展方法中使用UrlHelper,但它不是测试友好的代码。我会坚持下去。我知道帮手的作品。它不需要测试。我想封装UrlHepler,以便传递tilda前缀的字符串。 – onefootswill 2013-03-19 11:37:54

1

当我碰上.NET类型不属于单元测试友好的,我通常写我自己的接口(只有我需要的方法)和垫片类实现这只是转发方法/属性调用原始类的界面。垫片可通过检查进行测试。

然后我写的一切,我需要对这个接口的单元测试代码(所以我依赖于抽象,而不是结核)。这包括扩展接口的扩展方法,而不是原始的具体类型。在这方面,测试扩展方法是new Mock<IHtmlHelper>() ...容易 - 你可以让IHtmlHelper做你喜欢的东西,因为你必须在你的单元测试其行为的完全控制。

打字界面和垫片是具有较大接口的类有点乏味,但主要是我找到的开销非常低。这也意味着我最终会做更少奇怪的技巧来让事情变得可测试,所以我的代码更加一致且易于遵循(依赖总是以相同的方式注入,测试总是以相同的方式写入)。

我认为Husein Roncevic所指出的一点是,您应该在可观察状态而非行为方面测试客户HtmlHelper。换句话说,客户端代码的单元测试不应该知道调用了哪些方法(扩展方法或其他方法)。这听起来像你想单元测试扩展方法本身,这是一个非常合理的事情。

+0

这是正确的。我想测试扩展方法本身。这可能不是什么大不了的事。我知道它的工作原理,我不做TDD。但我确实写了单元测试,并且希望获得尽可能多的覆盖范围。 – onefootswill 2013-03-18 22:05:36