使用AutoMoq创建一个控制器时Fixture.CreateAnonymous方法杀死测试运行过程中有一个错误(AutoFixture) [英] Fixture.CreateAnonymous method kills test runner process with an error (AutoFixture) when using AutoMoq to create a Controller

查看:107
本文介绍了使用AutoMoq创建一个控制器时Fixture.CreateAnonymous方法杀死测试运行过程中有一个错误(AutoFixture)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图用AutoMoqCustomization与AutoFixture在通过Fixture.CreateAnonymous方法的单元测试创​​建ASP.NET MVC2控制器。我试图在这两个的xUnit TestDriven.NET下,该测试的xUnit GUI和MSTest的,并都具有相同的结果:过程运行测试一个巨大的失败。在Windows 7 X64的,如果是重要的。

I'm trying to use the AutoMoqCustomization with AutoFixture to create an ASP.NET MVC2 Controller in a unit test via the Fixture.CreateAnonymous method. I've tried in both xUnit under TestDriven.NET, the xUnit test GUI and in MSTest and all have the same result: a massive failure of the process running the test. On Windows 7 x64 if that matters.

要复制,只需创建一个新的ASP.NET MVC2项目,添加到AutoFixture,AutoMoq和起订量的参考(3.1,按照该AutoMoq源),并尝试以下(REPRO VS2010 MVC2项目下面的链接):

To reproduce, simply create a new ASP.NET MVC2 project, add the references to AutoFixture, AutoMoq and Moq (3.1, as per the AutoMoq source) and try the below (repro VS2010 MVC2 project link below):

[TestMethod]
public void Index()
{
 var fixture = new Fixture().Customize(new AutoMoqCustomization());
    // here's where the error in the test host occurs:
 HomeController controller = fixture.CreateAnonymous<HomeController>();
}

在MSTest的错误读取:

In MSTest the error reads:

运行时遇到一个致命错误。错误的地址在0x6465f370,上线0x2684。错误code是0000005。这个错误可能是在CLR或用户code的不安全或非可验证部分的错误。这个bug的常见来源包括COM的互操作或用户的PInvoke封送处理错误,这可能会损坏堆栈。

The runtime has encountered a fatal error. The address of the error was at 0x6465f370, on thread 0x2684. The error code is 0xc0000005. This error may be a bug in the CLR or in the unsafe or non-verifiable portions of user code. Common sources of this bug include user marshaling errors for COM-interop or PInvoke, which may corrupt the stack.

AfWithMvc摄制项目(从SkyDrive中)

推荐答案

建议的解决方案

要开始一个可能的解决方案,这应该停止崩溃:

To start with a possible solution, this should stop the crashing:

var fixture = new Fixture().Customize(new AutoMoqCustomization());
// This should fix the problem for all Controllers
fixture.Customize<ViewDataDictionary>(c =>
    c.Without(x => x.ModelMetadata));

HomeController controller = fixture.CreateAnonymous<HomeController>();

说明

和现在的解释:

此测试错误是由AutoFixture的造成的 AutoProperties 的功能,试图分配一个值 HomeController.ViewData.ModelMetaData 。该ModelMetaData类有此构造:

This test error is caused by AutoFixture's AutoProperties feature trying to assign a value to HomeController.ViewData.ModelMetaData. The ModelMetaData class has this constructor:

public ModelMetadata(
    ModelMetadataProvider provider,
    Type containerType,
    Func<object> modelAccessor,
    Type modelType,
    string propertyName)

这里的罪魁祸首是 modelAccessor ​​参数。为了填补这个属性AutoFixture(而不是盲目地)反映了类型,并认为这一个构造函数:

The culprit here is the modelAccessor parameter. To fill that property AutoFixture (rather mindlessly) reflects over the type and finds this single constructor:

public Func(object @object, IntPtr method)

进一步挖掘,第一IntPtr的构造AutoFixture能满足是这个:

Digging further, the first IntPtr constructor AutoFixture can satisfy is this one:

public unsafe IntPtr(int value)

在默认情况下,创建href=\"http://blog.ploeh.dk/2009/04/03/CreatingNumbersWithAutoFixture.aspx\" rel=\"nofollow\">的Int32实例,所以在这种情况下可能会是1或2或类似的小整数。换句话说,我们现在有一个的非常无效的不安全在我们的手指针,而这正在使进程崩溃。

By default, Int32 instances are created by a deterministic rising sequence, so value in this case will probably be 1 or 2 or a similar small integer. In other words, we now have a very invalid unsafe pointer on our hands, and this is making the process crash.

现在,一般情况下,我们应该能够通过注册来解决这个 Func键&LT;对象&gt; 通过夹具,一切都应该花花公子:

Now, under normal circumstances we should be able to fix this by registering a Func<object> with the Fixture and everything should be dandy:

fixture.Register<Func<object>>(() => () => new object());

不过,我想这与你的摄制,虽然过程中不再以同样的方式崩溃,在测试运行了很长一段时间,最后用一个OutOfMemoryException崩溃。

However, I tried this with your repro and although the process no longer crashes in the same way, the test runs for a very long time and finally crashes with an OutOfMemoryException.

我不知道是什么ASP.NET MVC确实与 Func键&LT;对象&gt; ,但显然它使用它相当heaviliy

I don't know what ASP.NET MVC does with Func<object>, but apparently it uses it quite heaviliy.

现在的问题是,这是否是AutoFixture错误?

The question remains whether this is a bug in AutoFixture?

我相信,事实并非如此。虽然它肯定是不太理想,AutoFixture没有把funcs中或操作任何不同于其他类型的,这就是为什么我们看到的这种行为。

I believe that it isn't. While it is definitely less than ideal, AutoFixture doesn't treat Funcs or Actions any differently than other types, which is why we see this behavior.

这特定的行为也可能会被添加特定支持 Func键&LT解决,但要保持一致性,也应该有 Func键&LT支持; T,TResult&GT; Func键&LT; T1,T2,TResult&GT; 等AFAIR在.NET 4中还有的很多的这些委托类型(也动作等),因此这将意味着增加了对各类一大堆的支持。

This particular behavior could possibly be addressed by adding specific support for Func<TResult>, but to stay consistent it should also have support for Func<T, TResult>, Func<T1, T2, TResult>, etc. AFAIR in .NET 4 there are a lot of these delegate types (also Action, etc.), so that would mean adding support for a whole host of types.

但后来怎么样所有其他类型需要一个IntPtr在其构造? AutoFixture不可能知道所有这些,所以这似乎不像一个可行的方向。

But then what about all other types that take an IntPtr in their constructor? AutoFixture can't possibly know about them all, so this seems not like a viable direction.

然而,它的可能的已经是一个戒备的$ P从尝试摆在首位创建IntPtr的实例$ pvents它。这将极有可能在2.0 RTW之前加入。

However, what it could have is a guard that prevents it from attempting to create IntPtr instances in the first place. This will most likely be added before the 2.0 RTW.

感谢您报告这一点。

这篇关于使用AutoMoq创建一个控制器时Fixture.CreateAnonymous方法杀死测试运行过程中有一个错误(AutoFixture)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆