We have capital-U Unit Tests that are supposed to be testing a particular slice of our code. This code has a dependency on an IConverter<TIn, TOut>
(a wrapper similar to AutoMapper). The behavior of this converter is important for the overall system, but not for the behavior of the specific unit under test.
The code under test is similar to this:
var entity = repository.Load(id);
var dto = converter.Convert(entity);
return dto;
The unit test I would want to see are:
IRepository<Entity>.Load(Arg.Any()).Returns(fakeEntity);
IConverter<Entity, DTO>.Convert(Arg.Any()).Returns(fakeDto);
resultDto = Subject.DoStuff();
Assert.That(resultDto == fakeDto);
The unit tests I am seeing are more like:
IRepository<Entity>.Load(Arg.Any()).Returns(fakeEntity);
var converter = new ActualEntityConverter();
IConverter<Entity, DTO>.Convert(Arg.Any()).Returns(converter.Convert(Arg<Entity>()));
resultDto = Subject.DoStuff();
Assert.That(resultDto.Property1 == "actual converted value");
. . .
To me, this feels like excessive coupling. We already have tests that cover the integration between this service and the converter -- it's our integration tests. The developer writing this code is advocating for it because of 'free' code coverage. I would like him to mock the behavior of the converter to just return a DTO and not actually perform conversion behavior.
Pull requests submitted with these combined tests do not include unit tests covering the mapping/converter specifically.
Am I misunderstanding unit tests? Am I being overly pedantic? Is he misunderstanding unit tests vs integration tests?
fakeEntity
implementIEquatable<FakeEntity>
? Otherwise,resultDto == fakeDto
is reference equality, which isn't going to tell you much.