Use AutoFixture with classes with many constructors
Asked Answered
F

1

5

I have class with two different constructors:

public class A {
    public A(B b) { ... }
    public A(C c) { ... }
}

How can I configure AutoFixture for easy switching between this constructors?

I'd like AutoFixture create an instance of A with a constructor, for which arguments I explicitly specify the default value (call Register).

For example:

var fixture = new Fixture();
fixture.Register(() => new B("stateB"));
fixture.Create<A>(); // Calls constructor A(B b)

Can I achieve behavior like this with AutoFixtre? Or can you suggest another approach for configuration constructors?

I understand, that I can Customize fixture with TemplateMethodQUery constructor query strategy, but this method looks quite messy...

Freddafreddi answered 3/10, 2017 at 19:58 Comment(0)
T
7

In general, AutoFixture doesn't give you an API for specifying ad hoc constructor arguments in an untyped manner. This is by design.

AutoFixture was originally created as a tool for Test-Driven Development. In the spirit of GOOS one should listen to the tests. When the test becomes difficult to write, it's time to reconsider the design of the System Under Test (SUT). AutoFixture tends to amplify this effect.

Consider other options for dealing with, or testing against, particular constructor arguments, or overloads.

That said, here are some suggestions.

Use the constructor

The C# language already gives you a robust and type-safe way to create new objects with constructor arguments. Why not use that?

var fixture = new Fixture();
fixture.Register(() => new B("stateB"));
var b = fixture.Create<B>();

var a = new A(b);

You'll still get B value created by AutoFixture.

Register A

You can also use the Register mechanism:

var fixture = new Fixture();
fixture.Register(() => new B("stateB"));
fixture.Register((B b) => new A(b));

var a = fixture.Create<A>();

This will, obviously always use the constructor overload that takes a B value.

Use Get

Another option is to use the type-safe Get extension method:

var fixture = new Fixture();
fixture.Register(() => new B("stateB"));

var a = fixture.Get((B b) => new A(b));

This gives you an opportunity to construct A values in a slightly more ad hoc manner. This also enables you to reuse the same Fixture, but request another object that uses a different constructor overload:

var a = fixture.Get((C c) => new A(c));

Here, the c object is still created by AutoFixture.

The Get (and corresponding Do) method comes with overloads that support more arities for the lambda expression.

Timepiece answered 4/10, 2017 at 6:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.