سؤال

I set up a simple test project in Visual Studio 2010. For unit tests I use nunit 2.6.1 and for mocking FakeItEasy 1.7.4582.63 which I install via NuGet.

I try to fake a DbDataAdapter using the following code:

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

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

When I run the test using .NET framework 3.5 everything works fine and test1 will pass. But, when I set the framework version to .NET 4.0, I get the following exception:

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.

Any ideas how to make things work in .NET 4.0 are appreciated!

Bye, Jörg

هل كانت مفيدة؟

المحلول

Usually such problems come not from FakeItEasy itself, but from Castle.DynamicProxy, library which FakeItEasy uses to create fake types. Investigating this little further leads to following exception thrown by Castle:

Due to limitations in CLR, DynamicProxy was unable to successfully replicate non-inheritable attribute System.Security.Permissions.PermissionSetAttribute on System.Data.Common.DbDataAdapter.CloneInternals. To avoid this error you can chose not to replicate this attribute type by calling 'Castle.DynamicProxy.Generators.AttributesToAvoidReplicating.Add(typeof(System.Security.Permissions.PermissionSetAttribute))'.

Inspecting DbDataAdapter base class' source code (DataAdapter) shows that this indeed is the case:

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

Castle already hinted how to solve this problem. Before creating your fake, simply instruct Castle not to replicate PermissionSetAttribute:

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

Two things to note:

  1. You need to reference Castle.Core.dll in your project (available here)
  2. Keep in mind FakeItEasy will only be able to mock virtual methods of this DbDataAdapter (again, this is Castle.DynamicProxy/CLR limitation - I briefly explained why this is the case in my blog post)
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top