Autofixture: Is it possible to create an instance based on a runtime `System.Type`?

Created on 16 Nov 2017  ·  3Comments  ·  Source: AutoFixture/AutoFixture

For making sure my AutoMapper mappings don't blow up, I have a test class similar to the following:

public class MapperTests
{
    private readonly IMapper _mapper; // from AutoMapper
    private readonly IFixture _fixture;

    public MapperTests()
    {
        _mapper = SetUpAutoMapper();
        _fixture = new Fixture();
    }

    [Theory]
    [InlineData(typeof(Foo), typeof(Bar))]
    [InlineData(typeof(Boo), typeof(Far))]
    // etc ...
    public void CanMapTypes(Type inputType, Type outputType)
    {
        var input = _fixture.Create(inputType);

        // throws exceptions if something's broken:
        _mapper.Map(input, outputType)
    }
}

I just discovered that _fixture.Create(inputType) doesn't actually create an instance of the type (e.g. a Foo in the first test) but actually an instance of System.Type. This, of course, renders my test fairly useless.

I looked through the available methods (just browsing IntelliSense) but couldn't find one that seemed to match my expectations. Is there a way to do what I want here; basically create an instance of a type provided at runtime?

question

Most helpful comment

Thanks!

By reading the source code of the generic fixture.Create<T>() object, figuring out where it eventually ends up, I also found out that this works:

var input = new SpecimenContext(_fixture).Resolve(sourceType);

I guess they are more or less equivalent :) Thanks a lot!

All 3 comments

It seems that I know what is going on 😄

If you try the AutoFixture v4, you will find that this code doesn't compile. The reason is that we extracted confusing Create() method overloads to a separate package, so only users who knows what they are doing should use them.

```c#
_fixture.Create(inputType);

It might look that you are making a request of `typeof(Foo)` here, however in reality you are passing this argument as a `seed` and the actual request type is `typeof(Type)`.  To fix the issue please tune a bit your code:

```c#
public class Foo
{
}

[Theory]
[InlineData(typeof(Foo))]
public void TestTypeRequest(Type requestType)
{
    var fixture = new Fixture();
    var result = fixture.Create(requestType, new SpecimenContext(fixture));

    Assert.IsAssignableFrom<Foo>(result);
}

API is probably not succinct, however your scenario is not common, so that should be fine.

Let me know whether that helped 😉

Thanks!

By reading the source code of the generic fixture.Create<T>() object, figuring out where it eventually ends up, I also found out that this works:

var input = new SpecimenContext(_fixture).Resolve(sourceType);

I guess they are more or less equivalent :) Thanks a lot!

@tlycken Indeed, both snippets do the same, while your option looks much better :) Will use it in future if needed :blush:

Was this page helpful?
0 / 5 - 0 ratings