注册.单元使用AutoFixture测试Html Helper

Spo*_*ock 3 autofixture

最初的问题是: 使用AutoFixture对Html Helper进行单元测试

不确定我是否应该重新打开原来的问题; 但是,由于我将原始问题标记为已解决,因此我决定创建一个新问题.如果我做错了,请道歉.

我正在使用Mark建议的方法,但在使用Freeze时我遇到了困难.

以下是完整的源代码...... Class Under Test:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace MvcDemo2.Helpers
{
      public static class Keys
      {
          public static readonly string SomeKey = "SomeKey";
      }

      public static class SampleHelpers
      {
          public static MvcHtmlString SampleTable(this HtmlHelper helper, 
            SampleModel model, IDictionary<string, object> htmlAttributes)
          {
                if (helper == null)
                {
                    throw new ArgumentNullException("helper");
                }

                if (model == null)
                {
                    throw new ArgumentNullException("model");
                }

                TagBuilder tagBuilder = new TagBuilder("table");
                tagBuilder.MergeAttributes(htmlAttributes);                               
                tagBuilder.GenerateId(helper.ViewContext.
                                 HttpContext.Items[Keys.SomeKey].ToString());
                return MvcHtmlString.Create(
                         tagBuilder.ToString(TagRenderMode.Normal));
            }
      }
  }


  public class SampleModel
  {
  }
}
Run Code Online (Sandbox Code Playgroud)

单元测试是为了确保HttpContext中指定键的Html按预期返回

public void SampleTableHtmlHelper_WhenKeyExistWithinHttpContext_ReturnsExpectedHtml()
Run Code Online (Sandbox Code Playgroud)

我将夹具配置如下

var fixture = new Fixture().Customize(new AutoMoqCustomization());
Run Code Online (Sandbox Code Playgroud)

然后在ViewContext上冻结:

var vc = fixture.Freeze<ViewContext>();
Run Code Online (Sandbox Code Playgroud)

我得到以下异常:

错误1测试"MvcDemo2.Tests.Controllers.SampleHelpersTestsAutoFixture.SampleTableHtmlHelper_WhenKeyExistWithinHttpContext_ReturnsExpectedHtml"失败:System.Reflection.TargetInvocationException:异常已通过调用的目标引发异常.---- System.NotImplementedException:未实现方法或操作.在System.RuntimeMethodHandle._InvokeMethodFast在System.RuntimeMethodHandle.InvokeMethodFast(IRuntimeMethodInfo方法,对象目标(IRuntimeMethodInfo方法,对象目标,对象[]参数,SignatureStruct&SIG,MethodAttributes methodAttributes,RuntimeType typeOwner),对象[]参数,签名Sig,MethodAttributes methodAttributes ,RuntimeType typeOwner)在System.Reflection.RuntimeMethodInfo.Invoke(对象OBJ,的BindingFlags invokeAttr,粘结剂粘结剂,在System.Reflection.RuntimeMethodInfo.Invoke(对象OBJ,的BindingFlags invokeAttr,粘结剂粘结剂对象[]参数,CultureInfo的文化,布尔skipVisibilityChecks) ,对象[]参数,CultureInfo的培养)
在System.Reflection.RuntimePropertyInfo.SetValue(对象OBJ,对象的值,的BindingFlags invokeAttr,粘结剂粘结剂,在System.Reflection.RuntimePropertyInfo.SetValue(对象OBJ对象[]索引,CultureInfo的培养物), Ploeh.AutoFixture.Kernel.AutoPropertiesCommand中的对象值,Object [] index)1.Create 1.Execute(T specimen, ISpecimenContext context) at Ploeh.AutoFixture.Kernel.Postprocessor(对象请求),Ploeh.AutoFixture上的System.Linq.Enumerable.WhereSelectListIterator 2.MoveNext() at System.Linq.Enumerable.d__a5 1 source)上的Ploeh.AutoFixture.Kernel.CompositeSpecimenBuilder .<> c__DisplayClass6.b__1(ISpecimenBuilder b),ISpecimenContext context).Kernel.CompositeSpecimenBuilder.Create在Ploeh.AutoFixture.Kernel.RecursionGuard.Create在Ploeh.AutoFixture.Kernel.SpecimenContext.Resolve(对象请求)在Ploeh.AutoFixture.Kernel(对象请求,ISpecimenContext上下文)(对象请求,ISpecimenContext上下文) .SeedIgnoringRelay.Create在Ploeh.AutoFixture.Kernel.CompositeSpecimenBuilder(对象请求,ISpecimenContext上下文).<> c__DisplayClass6.b__1(ISpecimenBuilder b)在System.Linq.Enumerable.WhereSelectListIterator 2.MoveNext() 在System.Linq.Enumerable.d__a5 1在Ploeh.AutoFixture.Kernel.CompositeSpecimenBuilder.Create(对象请求,ISpecimenContext上下文)在Ploeh.AutoFixture.Kernel.Postprocessor源)2.MoveNext() 在System.Linq.Enumerable.WhereSelectEnumerableIterato ř 1.MoveNext() 在System.Linq.Enumerable.FirstOrDefault [TSource](IEnumerable的2范围,HttpContextBase HttpContext的)在System.Web.Mvc.ViewContext.SetClientValidationEnabled(布尔启用,IDictionary`2范围,HttpContextBase HttpContext的)在系统. Web.Mvc.ViewContext.set_ClientValidationEnabled(布尔值)C:\ Users ... 78 2.MoveNext()
at System.Linq.Enumerable.WhereSelectEnumerableIterator

1.MoveNext()
at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable
2.MoveNext()
at System.Linq.Enumerable.WhereSelectEnumerableIterator

1.MoveNext()
at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable
1.Create(Object request, ISpecimenContext context) at Ploeh.AutoFixture.Kernel.CompositeSpecimenBuilder.<>c__DisplayClass6.<Create>b__1(ISpecimenBuilder b) at System.Linq.Enumerable.WhereSelectListIterator
2.MoveNext()
at System.Linq.Enumerable.<DefaultIfEmptyIterator>d__a5

1 source) at Ploeh.AutoFixture.Kernel.CompositeSpecimenBuilder.Create(Object request, ISpecimenContext context) at Ploeh.AutoFixture.Kernel.RecursionGuard.Create(Object request, ISpecimenContext context) at Ploeh.AutoFixture.Kernel.SpecimenContext.Resolve(Object request) at Ploeh.AutoFixture.SpecimenFactory.CreateAnonymous[T](ISpecimenContext context, T seed) at Ploeh.AutoFixture.SpecimenFactory.CreateAnonymous[T](ISpecimenBuilderComposer composer, T seed) at Ploeh.AutoFixture.FixtureFreezer.Freeze[T](IFixture fixture, T seed)
at MvcDemo2.Tests.Controllers.SampleHelpersTestsAutoFixture.SampleTableHtmlHelper_WhenKeyExistWithinHttpContext_ReturnsExpectedHtml() in C:\Users\...:line 78 ----- Inner Stack Trace ----- at System.Web.HttpContextBase.get_Items() at System.Web.Mvc.ViewContext.ScopeCache.Get(IDictionary

当它试图设置属性ViewContext.SetClientValidationEnabled的值时似乎失败了.

我坚持这个.任何想法都非常感激.

Mar*_*ann 5

好吧,如果你考虑内部堆栈跟踪,你会注意到异常被抛出HttpContextBase.Items.如果您使用反射工具查看实现,您会发现此虚拟方法抛出NotImplementedException - 谈论POLA违规.BCL中的很多Web抽象都是这样做的,这真的非常痛苦.

我不确定它会对你有什么帮助,但你可以通过关闭ViewContext类的AutoProperties来解决这个问题,如下所示:

fixture.Customize<ViewContext>(c => c.OmitAutoProperties());
Run Code Online (Sandbox Code Playgroud)