【问题标题】:Creating a fake DbDataAdapter throws FakeItEasy.Core.FakeCreationException创建假 DbDataAdapter 会引发 FakeItEasy.Core.FakeCreationException
【发布时间】:2012-08-11 19:32:31
【问题描述】:

我在 Visual Studio 2010 中设置了一个简单的测试项目。对于单元测试,我使用 nunit 2.6.1 并模拟我通过 NuGet 安装的 FakeItEasy 1.7.4582.63。

我尝试使用以下代码伪造 DbDataAdapter:

using System.Data.Common;
using FakeItEasy;
using NUnit.Framework;

namespace huhu
{
    [TestFixture]
    public class Class1
    {
        [Test]
        public void test1()
        {
            A.Fake<DbDataAdapter>();
        }
    }
}

当我使用 .NET framework 3.5 运行测试时,一切正常,test1 将通过。但是,当我将框架版本设置为 .NET 4.0 时,出现以下异常:

FakeItEasy.Core.FakeCreationException : 
  Failed to create fake of type "System.Data.Common.DbDataAdapter".

  Below is a list of reasons for failure per attempted constructor:
    No constructor arguments failed:
      No default constructor was found on the type System.Data.Common.DbDataAdapter.
    The following constructors were not tried:
      (*System.Data.Common.DbDataAdapter)

      Types marked with * could not be resolved, register them in the current
      IFakeObjectContainer to enable these constructors.

任何关于如何在 .NET 4.0 中运行的想法都值得赞赏!

再见,约尔格

【问题讨论】:

    标签: c# unit-testing fakeiteasy


    【解决方案1】:

    通常这些问题不是来自 FakeItEasy 本身,而是来自Castle.DynamicProxy,FakeItEasy 用来创建假类型的库。进一步调查这一点会导致 Castle 抛出以下异常:

    由于 CLR 中的限制,DynamicProxy 无法成功复制 System.Data.Common.DbDataAdapter.CloneInternals 上的不可继承属性 System.Security.Permissions.PermissionSetAttribute。 为避免此错误,您可以选择不复制此属性类型,方法是调用“Castle.DynamicProxy.Generators.AttributesToAvoidReplicating.Add(typeof(System.Security.Permissions.PermissionSetAttribute))”。

    检查 DbDataAdapter 基类的源代码 (DataAdapter) 表明情况确实如此:

    [PermissionSet(SecurityAction.Demand, Name = "FullTrust")]
    protected virtual DataAdapter CloneInternals()
    

    城堡已经暗示了如何解决这个问题。在创建假之前,只需指示 Castle 不要复制 PermissionSetAttribute

    Castle.DynamicProxy.Generators
       .AttributesToAvoidReplicating.Add(typeof(PermissionSetAttribute));
    var fake = A.Fake<DbDataAdapter>();
    

    需要注意的两点:

    1. 您需要在您的项目中引用 Castle.Core.dll(可用here
    2. 请记住,FakeItEasy 只能模拟此 DbDataAdapter 的虚拟方法(同样,这是 Castle.DynamicProxy/CLR 限制 - 我在 my blog post 中简要解释了为什么会出现这种情况)

    【讨论】:

    • 天啊!这有帮助!非常感谢!但是,我仍然想知道为什么仅在使用 .NET 4.0 时才引发此异常 - 我刚刚在 .NET 3.5 类库中设置了相同的测试,在该类库中生成了假货,没有任何投诉。我在Microsoft 下载的 .NET_3.5_sp1_redist 中找到了 DataAdapter.cs 并找到了相同的 PermissionSetAttribute...
    • 3.5 和 4.0 之间的类与安全性有关。 4.0 中增加的安全性导致了您的问题。
    猜你喜欢
    • 2015-02-12
    • 1970-01-01
    • 2012-12-11
    • 1970-01-01
    • 2011-03-30
    • 2015-01-14
    • 1970-01-01
    • 1970-01-01
    • 2020-03-15
    相关资源
    最近更新 更多