Easy way to specify the value of a single constructor parameter?

Is there any simple way in Autofixture for a new object using its constructor, but hard-code / specify a value that will be used for one parameter in the constructor?

I see that this can be done with properties using something like:

fixture.Build<MyObj>().With(x=x.Val,"hard coded value").Create()

+8
c # autofixture
source share
1 answer

From the discussion of this issue in the comments:

Often I want to update an object, but only one parameter bothers me. Perhaps the value of the parameter controls the calculation or transformation of some kind. I want the value itself to be random, but the test needs to know which random value was chosen.

Assuming this is the main problem, I will try to solve this problem.

Set object

The simplest solution is to simply ask the object what the value is after AutoFixture created it:

 var fixture = new Fixture(); var mc = fixture.Create<MyClass>(); var specialValue = mc.SpecialValue; // Do something with specialValue... 

If you just need to know what a special meaning is, but you don't need it to have a specific meaning, you can use this technique.

This obviously requires you to set the value from the constructor parameter as a property (read-only), but a good idea anyway .

Assign value after creation

If you need the parameter to have a specific value, you can assign it after creation:

 var fixture = new Fixture(); var mc = fixture.Create<MyClass>(); mc.SpecialValue = "Some really special value"; 

This requires that you make the value available as a record property. Although I personally am not a big fan of this, because it makes the object mutable, many people already design their objects this way, and if so, why not use it?

Use copy-and-update after creation

If you want your objects to be immutable, you can still use a variant of the above technique. In F #, you can use the so-called copy and update expressions to achieve the same goal. In F #, it will be something like:

 let fixture = Fixture () let mc = { fixture.Create<MyRecord> () with SpecialValue = "Some special value!" } 

You can emulate this in C # by suggesting methods for copying and updating classes so you can write something like this:

 var fixture = new Fixture(); var mc = fixture .Create<MyClass>() .WithSpecialValue("Some really special value"); 

This is the method that I use all the time in my C # code. AutoFixture has an idiomatic statement to test such copy and update methods .

Enter a value for the parameter

If you can live by injecting a fixed value for a specific constructor parameter, you can do this with the building blocks of the AutoFixture core. This test demonstrates how to:

 [Fact] public void CustomizeParameter() { var fixture = new Fixture(); fixture.Customizations.Add( new FilteringSpecimenBuilder( new FixedBuilder("Ploeh"), new ParameterSpecification( typeof(string), "specialValue"))); var actual = fixture.Create<MyClass>(); Assert.Equal("Ploeh", actual.SpecialValue); } 

However, this leads to the fact that this parameter will always be β€œPloeh” for this fixture instance. It is also refactoring-unsafe as it is based on a string referring to the parameter name.

+10
source share

All Articles