Reputation: 13
Using Autofixture 3.46 AutoData attribute from Autofixture.xUnit2 3.46, and xunit2, instantiating Sum in the test method parameter, I get an Xunit.sdk.EqualException from the Assert.
[Theory ]
[AutoData]
public void ShouldBeSum_AutoData(int a, int b, Sum uut )
{
//problem
int residue = uut.Value; //not zero!
//fix
uut.Value = 0;
//Arrange - in the parameter leads to problem
// var uut =new Sum();
//Act
uut.Add(a);
uut.Add(b);
//Assert
Assert.Equal(a + b, uut.Value);
}
It seems the property value of the new Sum instance is not set to a default for the type (say zero) on instantiation- evidence the non zero value of 'residue'.
public class Sum
{
public int Value { get; set; }
public void Add(int number)
{
Value += number;
}
}
Instantiation of the test target uut from the body (and with new) gives the expected default initial property values. So the uut class is incompletely instantiated from a parameter at present - it's your responsibility.
A fix on the way?
Upvotes: 1
Views: 109
Reputation: 233125
This behaviour is by design. AutoFixture is designed to create and fill data into objects, so that's its default behaviour.
There are many ways in which you can disable AutoProperties in AutoFixture. In this particular example, the lightest fix is to apply the [NoAutoProperties]
attribute to the uut
argument:
[Theory, AutoData]
public void ShouldBeSum_AutoData(int a, int b, [NoAutoProperties]Sum uut)
{
uut.Add(a);
uut.Add(b);
Assert.Equal(a + b, uut.Value); // Passes
}
There are other, more wholesale, ways of achieving the same result, though.
Finally, this ought to give pause to reflect on the design of Sum
: is it appropriate that Value
is a publicly modifiable property? Shouldn't the invariants of the Sum
class be that Value
is guaranteed to be the result of performing calculations with the class (i.e. by calling Add
)?
Such a design could look like this:
public class Summer
{
public int Value { get; private set; }
public void Add(int number)
{
Value += number;
}
}
in which case the following test automatically passes:
[Theory, AutoData]
public void ShouldBeSum_AutoData(int a, int b, Summer uut)
{
uut.Add(a);
uut.Add(b);
Assert.Equal(a + b, uut.Value); // Passes
}
AutoFixture was originally build as a tool for Test-Driven Development (TDD), and TDD is all about feedback. In the spirit of GOOS, you should listen to your tests. If the tests are hard to write, you should consider your API design. AutoFixture tends to amplify that sort of feedback, so a good reaction to trouble with AutoFixture is to look at the SUT before looking at AutoFixture itself.
Upvotes: 2