I'm using Autofixture for my unit tests, with auto-generated data.
To test a simple Controller endpoint (Get employee by Id), I'm doing something similar to this:
[Theory, AutoData]
public void GetEmployeeById_ValidId_ReturnsExpectedModel(
EmployeeModel expectedEmployee,
[Frozen] Mock<IEmployeeService> employeeServiceMock,
EmployeesController sut)
{
employeeServiceMock
.Setup(x => x.GetEmployeeById(42))
.Returns(expectedEmployee);
var actual = sut.GetEmployeeById(42);
actual.As<OkObjectResult>().Value.As<EmployeeModel>()
.Should().BeEquivalentTo(expectedEmployee);
}
And the controller:
[HttpGet("{id:int}")]
public IActionResult GetEmployeeById(int id)
{
var employee = employeeService.GetEmployeeById(id);
if (employee == null)
return NotFound("Employee not found");
return Ok(employee);
}
In this unit test, expectedEmployee is auto-generated with 'random' data. The sut (System Under Test) is configured to be generated with all its required dependencies (one of them is IEmplyeeService).
The problem with this unit test is that, if I change the employee before returning it from the controller, the test would still pass (because it's referencing the same object):
employee.SomeInternalModel.FooProperty = "Foo";
return Ok(employee);
So, I consider the above unit test to be bad.
To make the unit test fail in this scenario, I need to pass a separate object: deep copy of the EmployeeModel:
employeeServiceMock
.Setup(x => x.GetEmployeeById(42))
.Returns(expectedEmployee.DeepCopy());
I don't have time and resources to write deep copy methods for all my models.
How to easily auto-generate identical models? I thought about seed-ing the AutoFixture but it doesn't seem to support this feature.
Do you have any elegant suggestions?