创建一个假的DbDataAdapter会抛出FakeItEasy.Core.FakeCreationException

时间:2012-08-06 08:35:34

标签: c# unit-testing fakeiteasy

我在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工作的想法都值得赞赏!

再见,Jörg

1 个答案:

答案 0 :(得分:3)

通常这些问题不是来自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已经暗示如何解决这个问题。在创建假冒之前,只需指示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中出现这种情况)