有没有简单的方法来测试helper.Action它是否调用了正确的参数。这是因为一些评论指出HtmlHelper不是可以嘲笑的,Action也是一个静态扩展。但是你可以使用一个解决方法来测试特定的场景,例如根据你的问题。
它只是需要一个测试,可能会嘲笑操作方法返回 什么特别,因此可以断言它被称为与 正确的参数。
虽然由于静态本质,这不是完全可能的,但我们可以使用不同的技术来验证Action是否已用正确的参数调用。
这只是指导,我还没有完全测试我的代码。我知道它可以在测试环境中工作,但我不完全确定这将在生产代码执行期间产生正确的结果。如果不是,我很乐意再看一遍..
首先我会创建一个类,允许我重写helper.Action方法。
public class HtmlHelperActionInvoker {
public virtual MvcHtmlString InvokeAction(HtmlHelper helper, string action, string controller) {
return helper.Action(action, controller);
}
}
然后在你的HTML辅助类,我想补充的静态构造函数和一个代表/ FUNC,让我在测试执行过程中设置自己HtmlHelpActionInvoker版本。
public static class SomeHtmlHelperClass
{
static SomeHelperClass() {
HtmlHelperActionFunc =() => new HtmlHelperActionInvoker();
}
public static Func<HtmlHelperActionInvoker> HtmlHelperActionFunc { get; set; }
public static MvcHtmlString RenderCMSObject(this HtmlHelper helper, CMSObject cmsObject)
{
var actionName = string.IsNullOrEmpty(cmsObject.ActionName)
? "Index"
: cmsObject.ActionName;
var controllerName = string.IsNullOrEmpty(cmsObject.ControllerName)
? "Default"
: cmsObject.ControllerName;
var helperAction = HtmlHelperActionFunc();
return helperAction.InvokeAction(helper, actionName, controllerName);
}
}
我相信静态CTRO将执行一次,producion代码执行过程中,一旦设定HtmlHelperActionInvoker的一个实例。随后的请求将重用此实例。 (正如我之前提到的,你可能需要测试这更)
现在的单元测试
我们将使用一种叫做Extract & Override技术。
在您的测试区域中创建一个可测试版本的HtmlHelperActionInvoker。这不是一个假对象/存根/模拟。这是HtmlHelperActionInvoker的可测试版本。只用于非常方法已被称为预期的参数。
public class TesatableHtmlHelperAction : HtmlHelperActionInvoker
{
public string Controller { get; set; }
public string Action { get; set; }
public override MvcHtmlString InvokeAction(HtmlHelper helper, string action, string controller) {
Action = action;
Controller = controller;
return new MvcHtmlString("");
}
}
在单元测试中,我们将设置可测试TesatableHtmlHelperAction所以SUT(测试系统)将执行检验的版本。 (注:它仍然被视为真正的,因为我们覆盖了真正的HtmlHelperActionInvoker的行为)
[TestMethod]
public void HtmlHelperActionRenderCMSObject_Execute_EnsureInvokeActionCalledWithExpectedControlerAndActionName()
{
//Arrange
var fakecmsObject = new CMSObject() { ActionName = "foo", ControllerName = "bar" };
var testableHtmlHelperAction = new TesatableHtmlHelperAction();
SomeHelperClass.HtmlHelperActionFunc =() => testableHtmlHelperAction;
// Act
SomeHelperClass.RenderCMSObject(null, fakecmsObject);
// Verify
Assert.AreEqual<string>(fakecmsObject.ActionName, testableHtmlHelperAction.Action);
Assert.AreEqual<string>(fakecmsObject.ControllerName, testableHtmlHelperAction.Controller);
}
你测试了什么行为? –
HTML帮助程序将使用正确的操作名称和控制器名称执行操作。实际的帮手方法比示例更复杂,但我简化了它以仅显示需要断言的区域。 – makit
通常情况下,单元测试用于验证除简单参数传递之外的某些行为。这就是为什么我们通常不测试自动属性的原因;我们只是假设他们工作。集成测试将涵盖这一点。 –