Disabling AutoProperties In AutoFixture by Mark Seemann
Since AutoFixture is a Test Data Builder, one of its most important tasks is to build up graphs of fully populated, yet semantically correct, strongly typed objects. As such, its default behavior is to assign a value to every writable property in the object graph.
While this is sometimes the desired behavior, at other times it is not.
This is particularly the case when you want to test that a newly created object has a property of a particular value. When you want to test the default value of a writable property, AutoFixture's AutoProperty feature is very much in the way.
Let's consider as an example a piece of software that deals with vehicle registration. By default, a vehicle should have four wheels, since this is the most common occurrence. Although I always practice TDD, I'll start by showing you the Vehicle class to illustrate what I mean.
public class Vehicle { public Vehicle() { this.Wheels = 4; } public int Wheels { get; set; } }
Here's a test that ensures that the default number of wheels is 4 - or does it?
In fact the assertion fails because the actual value is 1, not 4.
[TestMethod] public void AnonymousVehicleHasWheelsAssignedByFixture() { // Fixture setup var fixture = new Fixture(); var sut = fixture.CreateAnonymous<Vehicle>(); // Exercise system var result = sut.Wheels; // Verify outcome Assert.AreEqual<int>(4, result, "Wheels"); // Teardown }
Why does the test fail when the value of Wheels is set to 4 in the constructor? It fails because AutoFixture is designed to create populated test data, so it assigns a value to every writable property. Wheels is a writable property, so AutoFixture assigns an integer value to it using its default algorithm for creating anonymous numbers. Since no other numbers are being created during this test, the number assigned to Wheels is 1. This is AutoFixture's AutoProperties feature in effect.
When you want to test constructor logic, or otherwise wish to disable the AutoProperties feature, you can use a customized Builder with the OmitAutoProperties method:
[TestMethod] public void VehicleWithoutAutoPropertiesWillHaveFourWheels() { // Fixture setup var fixture = new Fixture(); var sut = fixture.Build<Vehicle>() .OmitAutoProperties() .CreateAnonymous(); // Exercise system var result = sut.Wheels; // Verify outcome Assert.AreEqual<int>(4, result, "Wheels"); // Teardown }
The OmitAutoProperties method instructs AutoFixture to skip assigning automatic Anonymous Values to all writable properties in the object graph. Any properties specifically assigned by the With method will still be assigned.
The test using OmitAutoProperties succeeds.