代码之家  ›  专栏  ›  技术社区  ›  ZeroBugBounce

Fixture.CreateAnonymous工具方法在使用AutoMoq创建控制器时使用错误(AutoFixture)终止测试运行程序进程

  •  2
  • ZeroBugBounce  · 技术社区  · 15 年前

    我试着用AutoFixture的AutoMoqCustomization来创建一个ASP.NETMVC2控制器在单元测试中通过Fixture.CreateAnonymous工具方法。我在这两个地方都试过了测试驱动.NET,xUnit test GUI和in MSTest都有相同的结果:运行测试的进程出现了大规模故障。在Windows7x64上。

    [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中,错误为:

    AfWithMvc repro project (from SkyDrive)

    1 回复  |  直到 15 年前
        1
  •  4
  •   Mark Seemann    15 年前

    建议的解决方案

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

    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的 自动属性 尝试为其赋值的功能 HomeController.ViewData.ModelMetaData . ModelMetaData类具有以下构造函数:

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

    罪魁祸首是 modelAccessor

    public Func(object @object, IntPtr method)
    

    进一步挖掘,第一个IntPtr构造函数AutoFixture可以满足的是:

    public unsafe IntPtr(int value)
    

    默认情况下, Int32 instances are created by a deterministic rising sequence ,所以 value 非常无效 我们手上的指针不安全,这使得进程崩溃。

    现在,在正常情况下,我们应该可以通过注册 Func<object>

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

    但是,我用您的repro尝试了这个方法,虽然这个过程不再以同样的方式崩溃,但是测试运行了很长时间,最后以OutOfMemoryException崩溃。

    我不知道是什么ASP.NETMVC与 函数<对象>

    问题是这是否是AutoFixture中的一个bug?

    我相信不是这样的。虽然它确实不太理想,但AutoFixture对待函数或动作与其他类型没有任何不同,这就是为什么我们看到这种行为。

    可以通过添加对 Func<TResult> Func<T, TResult> , Func<T1, T2, TResult> 在.NET4中有 很多 对于这些委托类型(也包括Action等),这意味着要添加对整个类型主机的支持。

    但是其他所有在构造函数中使用IntPtr的类型呢?AutoFixture不可能知道所有这些,所以这似乎不是一个可行的方向。

    然而,它是什么 能够 有是一个 guard that prevents it from attempting to create IntPtr instances in the first place . 这很可能会添加到2.0 RTW之前。

    推荐文章