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

Related issues

zvirja picture zvirja  路  8Comments

ecampidoglio picture ecampidoglio  路  7Comments

joelleortiz picture joelleortiz  路  4Comments

Eldar1205 picture Eldar1205  路  5Comments

Ridermansb picture Ridermansb  路  4Comments