AutoFixture无法创建声明(使用.NET Framework 4.6)

时间:2015-07-21 08:16:40

标签: c# visual-studio-2015 autofixture .net-4.6

我刚安装了VS2015,同时安装了.NET Framework 4.6,突然AutoFixture 3.30.8无法创建Claim对象。 我猜测新的.NET Framework版本4.6在AutoFixture中引起了一些问题。

我创建了一个测试项目(针对.NET Framework 4.5.1),其中包含VS2013中的以下代码:

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Ploeh.AutoFixture;

namespace AutoFixtureTester
{
    [TestClass]
    public class UnitTest1
    {
        [TestMethod]
        public void CanCreateClaim()
        {
            var fixture = new Fixture();
            fixture.Behaviors.Add(new OmitOnRecursionBehavior());

            var claim = fixture.Create<System.Security.Claims.Claim>(); // exception here

            Assert.IsNotNull(claim);
        }
    }
}

错误如下:

Ploeh.AutoFixture.ObjectCreationException: AutoFixture was unable to create an instance from System.IO.Stream, most likely because it has no public constructor, is an abstract or non-public type.

Request path:
         System.Security.Claims.Claim --> 
          System.IO.BinaryReader reader --> 
           System.IO.BinaryReader --> 
            System.IO.Stream input --> 
             System.IO.Stream
   at Ploeh.AutoFixture.Kernel.TerminatingWithPathSpecimenBuilder.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.BehaviorRoot.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.Kernel.RecursionGuard.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.Kernel.RecursionGuard.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.Fixture.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.Kernel.SpecimenContext.Resolve(Object request)
   at Ploeh.AutoFixture.Kernel.SeedIgnoringRelay.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.Kernel.CompositeSpecimenBuilder.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.Kernel.CompositeSpecimenBuilder.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.AutoPropertiesTarget.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.Kernel.Postprocessor`1.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.Kernel.CompositeSpecimenBuilder.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.Kernel.TracingBuilder.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.Kernel.TerminatingWithPathSpecimenBuilder.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.BehaviorRoot.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.Kernel.RecursionGuard.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.Kernel.RecursionGuard.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.Fixture.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.Kernel.SpecimenContext.Resolve(Object request)
   at Ploeh.AutoFixture.Kernel.ParameterRequestRelay.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.Kernel.CompositeSpecimenBuilder.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.Kernel.CompositeSpecimenBuilder.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.AutoPropertiesTarget.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.Kernel.Postprocessor`1.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.Kernel.CompositeSpecimenBuilder.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.Kernel.TracingBuilder.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.Kernel.TerminatingWithPathSpecimenBuilder.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.BehaviorRoot.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.Kernel.RecursionGuard.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.Kernel.RecursionGuard.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.Fixture.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.Kernel.SpecimenContext.Resolve(Object request)
   at Ploeh.AutoFixture.Kernel.MethodInvoker.<>c__DisplayClass2.<Create>b__0(ParameterInfo pi)
   at System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext()
   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
   at Ploeh.AutoFixture.Kernel.MethodInvoker.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.Kernel.CompositeSpecimenBuilder.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.Kernel.CompositeSpecimenBuilder.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.AutoPropertiesTarget.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.Kernel.Postprocessor`1.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.Kernel.CompositeSpecimenBuilder.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.Kernel.TracingBuilder.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.Kernel.TerminatingWithPathSpecimenBuilder.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.BehaviorRoot.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.Kernel.RecursionGuard.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.Kernel.RecursionGuard.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.Fixture.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.Kernel.SpecimenContext.Resolve(Object request)
   at Ploeh.AutoFixture.Kernel.SeedIgnoringRelay.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.Kernel.CompositeSpecimenBuilder.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.Kernel.CompositeSpecimenBuilder.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.AutoPropertiesTarget.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.Kernel.Postprocessor`1.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.Kernel.CompositeSpecimenBuilder.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.Kernel.TracingBuilder.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.Kernel.TerminatingWithPathSpecimenBuilder.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.BehaviorRoot.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.Kernel.RecursionGuard.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.Kernel.RecursionGuard.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.Fixture.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.Kernel.SpecimenContext.Resolve(Object request)
   at Ploeh.AutoFixture.Kernel.ParameterRequestRelay.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.Kernel.CompositeSpecimenBuilder.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.Kernel.CompositeSpecimenBuilder.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.AutoPropertiesTarget.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.Kernel.Postprocessor`1.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.Kernel.CompositeSpecimenBuilder.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.Kernel.TracingBuilder.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.Kernel.TerminatingWithPathSpecimenBuilder.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.BehaviorRoot.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.Kernel.RecursionGuard.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.Kernel.RecursionGuard.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.Fixture.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.Kernel.SpecimenContext.Resolve(Object request)
   at Ploeh.AutoFixture.Kernel.MethodInvoker.<>c__DisplayClass2.<Create>b__0(ParameterInfo pi)
   at System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext()
   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
   at Ploeh.AutoFixture.Kernel.MethodInvoker.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.Kernel.CompositeSpecimenBuilder.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.Kernel.CompositeSpecimenBuilder.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.AutoPropertiesTarget.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.Kernel.Postprocessor`1.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.Kernel.CompositeSpecimenBuilder.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.Kernel.TracingBuilder.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.Kernel.TerminatingWithPathSpecimenBuilder.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.BehaviorRoot.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.Kernel.RecursionGuard.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.Kernel.RecursionGuard.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.Fixture.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.Kernel.SpecimenContext.Resolve(Object request)
   at Ploeh.AutoFixture.Kernel.SeedIgnoringRelay.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.Kernel.CompositeSpecimenBuilder.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.Kernel.CompositeSpecimenBuilder.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.AutoPropertiesTarget.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.Kernel.Postprocessor`1.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.Kernel.CompositeSpecimenBuilder.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.Kernel.TracingBuilder.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.Kernel.TerminatingWithPathSpecimenBuilder.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.BehaviorRoot.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.Kernel.RecursionGuard.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.Kernel.RecursionGuard.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.Fixture.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.Kernel.SpecimenContext.Resolve(Object request)
   at Ploeh.AutoFixture.SpecimenFactory.Create[T](ISpecimenContext context, T seed)
   at Ploeh.AutoFixture.SpecimenFactory.Create[T](ISpecimenContext context)
   at Ploeh.AutoFixture.SpecimenFactory.Create[T](ISpecimenBuilder builder)
   at AutoFixtureTester.UnitTest1.CanCreateClaim() in D:\Sandbox\AutoFixtureTester\AutoFixtureTester\UnitTest1.cs:line 16

在安装VS2015之前,这种创建用于工作的Claim对象的方法。实际上我把这个解决方案发送给了我的同事,他只安装了VS2013并且适用于他。

我注意到导航到Claim代码的F12显示了4.5.1 DLL中的元数据。是否存在VS2015安装程序搞砸4.5.1 DLL的问题?或者这可能是AutoFixture中的一个错误,安装4.6已经发掘出来了吗?

我将来自我的同事的System.Security.Claims.Claim的DotPeek输出与我的同事进行了比较。他的节目:

// Assembly location: C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.1\mscorlib.dll

我的展示:

// Assembly location: C:\Windows\Microsoft.NET\Framework\v4.0.30319\mscorlib.dll

他有5个构造函数采用stringClaimsIdentity 我有7个构造函数,包括2个新的构造函数:

public Claim(BinaryReader reader) { ... }

public Claim(BinaryReader reader, ClaimsIdentity subject) { ... }

我想这个案例的解决方法是以某种方式强制AutoFixture使用特定的构造函数。但它让我感到紧张的是,这一突破性的变化已经从微软的网络中滑落。还有其他类似的变化吗?

1 个答案:

答案 0 :(得分:3)

作为让AutoFixture像以前一样工作的解决方法,我自定义了创建Claim的方式来选择参数最多的构造函数。

fixture.Customize<System.Security.Claims.Claim>(
    c => c.FromFactory(new MethodInvoker(new GreedyConstructorQuery())));

这个问题的原因似乎是安装4.6已经影响了4.5.1 DLL。 Claim现在有7个构造函数,而2个新构造函数采用BinaryReader参数,该参数依赖于Stream,它不能由AutoFixture构造。幸运的是,AutoFixture很好且可配置:)

如上所述,这让我感到紧张的是,这一突破性变化已经在微软的网络中滑落。另外它让我担心,如果他们决定在未来将另一个构造函数添加到Framework 4.7中,取20个参数,包括BinaryReader,那么我们将再次上升到该小溪。