Search code examples
unit-testingautofixtureautomoq

Possible to Freeze a Mock of a func?


I want to test that my Func type is actually executed. To do that I have created a Mock, but I run into an Exception from Autofixture. I tried to Freeze just the Func (without the Mock) and this works. Can someone explain what's happening or guide me to the right way of doing this?

Exception message:

An exception of type 'Ploeh.AutoFixture.Kernel.IllegalRequestException' occurred in Ploeh.AutoFixture.dll but was not handled in user code Additional information: A request for an IntPtr was detected. This is an unsafe resource that will crash the process if used, so the request is denied. A common source of IntPtr requests are requests for delegates such as Func or Action. If this is the case, the expected workaround is to Customize (Register or Inject) the offending type by specifying a proper creational strategy.

Code:

public class DomainClassDummy
{
    public int Id { get; set; }
}

var frozenFunc = F.Freeze<Func<int, DomainClassDummy>>(); //works
var frozenMockOfFunc = F.Freeze<Mock<Func<int,DomainClassDummy>>>(); //fails 

Solution

  • This behavior is due to AutoConfiguredMoqCustomization.

    When AutoFixture is customized with AutoConfiguredMoqCustomization, it relays the creation of the Mock instances to a special builder. This builder, however, gets the inner type Func<int,DomainClassDummy> and creates a mock out of it, passing the two arguments of its constructor: objectand IntPtr and here is where the problem lies.

    The default builder for delegates, creates its instances out of a Linq Lambda Expression.

    To make it work, you'll have to create the mock yourself and inject it to AutoFixture. Injecting it is the same as freezing, except you specify the instance yourself, instead of telling AutoFixture to create one for you.

    Here is what you should do:

    var mockOfFunc = new Mock<Func<int, DomainClassDummy>>();
    F.Inject(mockOfFunc);