Search code examples
moqautofixtureautomoq

AutoFixture/AutoMoq: Unable to Create Instance (`BadImageFormatException`)


Below is a minimal example of the problem I am currently encountering:

using System.Net.WebSockets;
using AutoFixture;
using AutoFixture.AutoMoq;
using FluentAssertions;
using Xunit;

...

[Fact]
public void Test1()
{
    var fixture = new Fixture().Customize(new AutoMoqCustomization() { ConfigureMembers = true });
    var sut = fixture.Create<WebSocket>();
    sut.Should().NotBeNull();
}

[Fact]
public void Test2()
{
    var fixture = new Fixture().Customize(new AutoMoqCustomization() { ConfigureMembers = true });
    var sut = new Mock<WebSocket>().Object;
    fixture.Inject(sut);
    sut.Should().NotBeNull();
}
...

When I run the first test, I get the following exception:

AutoFixture.ObjectCreationExceptionWithPath : AutoFixture was unable to create an instance from Moq.Mock`1[System.IO.Stream] because creation unexpectedly failed with exception. Please refer to the inner exception to investigate the root cause of the failure.

Inner exception messages:
System.BadImageFormatException: An attempt was made to load a program with an incorrect format. (Exception from HRESULT: 0x8007000B)

The second test succeeds.

I would like to be able to create an instance of a class using AutoFixture which takes a WebSocket as a constructor parameter, without the need to inject a mock object first (ultimately, so that I can use an AutoMoqData attribute, and get rid of some boilerplate). Have I got any misusage or misunderstanding going on here, or would this be better placed as a GitHub issue? In the interim, is there anything I can do to work around this issue?


Solution

  • You observe this issue because of the AutoFixture's factory discovery strategy. When you try to create an object of an abstract type, AutoFixture still inspects the type to find a static factory method to activate the object. In your particular case, the WebSocket type contains such methods, so some of them is used. It looks like it doesn't work well with auto-generated input values, so fails with an exception.

    You can customize AutoFixture, to always mock the WebSocket type:

    fixture.Register((Mock<WebSocket> m) => m.Object);
    

    Just tested with the latest versions of products (AutoFixture 4.5.0, Moq 4.10.0) and it works like a charm.