最初的问题是: 使用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.Create1.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 ... 782.MoveNext()
at System.Linq.Enumerable.WhereSelectEnumerableIterator1.MoveNext()
at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable2.MoveNext()
at System.Linq.Enumerable.WhereSelectEnumerableIterator1.MoveNext()
at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable1.Create(Object request, ISpecimenContext context) at Ploeh.AutoFixture.Kernel.CompositeSpecimenBuilder.<>c__DisplayClass6.<Create>b__1(ISpecimenBuilder b) at System.Linq.Enumerable.WhereSelectListIterator2.MoveNext()
at System.Linq.Enumerable.<DefaultIfEmptyIterator>d__a51 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的值时似乎失败了.
我坚持这个.任何想法都非常感激.
好吧,如果你考虑内部堆栈跟踪,你会注意到异常被抛出HttpContextBase.Items.如果您使用反射工具查看实现,您会发现此虚拟方法抛出NotImplementedException - 谈论POLA违规.BCL中的很多Web抽象都是这样做的,这真的非常痛苦.
我不确定它会对你有什么帮助,但你可以通过关闭ViewContext类的AutoProperties来解决这个问题,如下所示:
fixture.Customize<ViewContext>(c => c.OmitAutoProperties());
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1217 次 |
| 最近记录: |