39

I have the following class:

class Foo
{
    public Foo(string str, int i, bool b, DateTime d, string str2)
    {
         .....
    }
}

I'm creating a Foo with AutoFixture:

var foo = fixture.Create<Foo>();

but I want AutoFixture to provide a known value for the str2 parameter and use the default behavior for every other parameter.

I tried implementing a SpecimenBuilder but I can't find a way to get the metadata associated with the request to know that I'm being called from the Foo constructor.

Is there any way to achieve this?

Ruben Bartelink
  • 59,778
  • 26
  • 187
  • 249
Orlando Osorio
  • 3,116
  • 7
  • 29
  • 52
  • 4
    Here's one option: http://stackoverflow.com/a/16954699/126014 – Mark Seemann Oct 02 '14 at 05:37
  • 3
    For completeness' sake, I also want to point out this: http://stackoverflow.com/a/18238876/126014 – Mark Seemann Oct 02 '14 at 05:38
  • 3
    Perhaps you'll find this helpful as well: http://stackoverflow.com/a/15561752/126014 – Mark Seemann Oct 02 '14 at 05:39
  • possible duplicate of [How do I use Autofixture (v3) with ICustomization, ISpecimenBuilder to deal with constructor parameter?](http://stackoverflow.com/questions/15531321/how-do-i-use-autofixture-v3-with-icustomization-ispecimenbuilder-to-deal-with) – Ruben Bartelink Oct 21 '14 at 06:02
  • While I voted to close, I'm conflicted as I a) want to know if [this answer of mine](http://stackoverflow.com/a/15550506/11635) is any use to you, and b) the title and simplicity of this question do have merit, which would suggest I should upvote (and answer it). Would a tailored/refreshed version of my other answer here make everyone happy - I'd hate to see the question just languish here unanswered? – Ruben Bartelink Oct 21 '14 at 06:12
  • Hey @MarkSeemann, please put those comments in an answer so that Ruben can mark it as the answer. Then it won't show up on Unanswered. – pashute Jan 20 '15 at 10:19

2 Answers2

17

As answered here you can have something like

public class FooArg : ISpecimenBuilder
{
    private readonly string value;

    public FooArg(string value)
    {
        this.value = value;
    }

    public object Create(object request, ISpecimenContext context)
    {
        var pi = request as ParameterInfo;
        if (pi == null)
            return new NoSpecimen(request);

        if (pi.Member.DeclaringType != typeof(Foo) ||
            pi.ParameterType != typeof(string) ||
            pi.Name != "str2")
            return new NoSpecimen(request);

        return value;
    }
}

and then you can register it like this

var fixture = new Fixture();
fixture.Customizations.Add(new FooArg(knownValue));

var sut = fixture.Create<Foo>();
Community
  • 1
  • 1
Orlando Osorio
  • 3,116
  • 7
  • 29
  • 52
9

This answers the similar problem but with custom type e.g. MyType. When given:

class Foo
{
    public Foo(string str, MyType myType)
    {
         .....
    }
}

class MyType
{
    private readonly string myType;

    public MyType(string myType)
    {
        this.myType = myType
    }
}

You can call

fixture.Customize<MyType>(c => c.FromFactory(() => new MyType("myValue")));
var foo = fixture.Build<Foo>();
bombek
  • 553
  • 1
  • 7
  • 23