I have the following setup:
A calendar controller that calls a calendar service that calls a calendar client wrapper that calls the client. Controller -> Service -> ClientWrapper -> Client.
I am making an integration test that mocks the lowest tier (the client) and calls the controller to see if the client was called correctly.
My CalendarControllerBuilder:
internal class CalendarControllerBuilder
{
public CalendarControllerBuilder()
{
CalendarClientMock = new Mock<ICalendarServiceClient>(MockBehavior.Strict);
}
public Mock<ICalendarServiceClient> CalendarClientMock { get; set; }
public CalendarControllerBuilder With(Mock<ICalendarServiceClient> calendarClientWrapperMock)
{
CalendarClientMock = calendarClientWrapperMock;
return this;
}
public CalendarController Create()
{
var calendarClientWrapperMock = new CalendarClientWrapper(CalendarClientMock.Object);
var calenderService = new CalendarService(calendarClientWrapperMock);
return new CalendarController(calenderService);
}
}
Test setup with customization registration:
internal class CalenderControllerCustomization : ICustomization
{
public void Customize(IFixture fixture)
{
fixture.Register<CalendarController>(() =>
{
// ----- ICalendarServiceClient mock setups -----
var calendarServiceClientMock = new Mock<ICalendarServiceClient>(MockBehavior.Strict);
calendarServiceClientMock.Setup(m => m.GetEvents(It.IsAny<DateTime>(), It.IsAny<DateTime>(), It.IsAny<CancellationToken>()))
.ReturnsAsync(fixture.Create<EventList>()).Verifiable();
return new CalendarControllerBuilder()
.With(calendarServiceClientMock)
.Create();
});
}
}
My automoq data attribute (using AutoFixture.Xunit2):
public class Attributes
{
public class AutoMoqDataAttribute<T> : AutoDataAttribute where T : ICustomization, new()
{
public AutoMoqDataAttribute()
: base(() => new Fixture()
.Customize(
new CompositeCustomization(
new AutoMoqCustomization(),
new T())))
{
}
}
public class AutoMoqDataAttribute : AutoDataAttribute
{
public AutoMoqDataAttribute()
: base(() => new Fixture()
.Customize(
new AutoMoqCustomization()))
{
}
}
}
My test that works fine and uses the customization registration:
[Theory]
[AutoMoqData<CalenderControllerCustomization>]
public async Task Test_GetAllEvents_ClientIsCalledCorrectlyAndReturnsCorrectData(
IFixture fixture,
[Frozen] Mock<ICalendarServiceClient> calendarServiceClientMock,
CalendarController sut)
{
// Arrange
var startDate = fixture.Create<DateTimeOffset>();
var endDate = fixture.Create<DateTimeOffset>();
// Act
var eventList = await sut.GetAllEvents(startDate, endDate);
// Assert
eventList.Events.Count.Should().Be(3); // fixture always create 3 of lists here
calendarServiceClientMock.Verify();
}
THE PROBLEM:
Now I want to override the setup with my own data returned.
[Theory]
[AutoMoqData<CalenderControllerCustomization>]
public async Task Test_GetAllEvents_ClientIsCalledCorrectlyAndReturnsCorrectData_Overridden(
IFixture fixture,
[Frozen] Mock<ICalendarServiceClient> calendarServiceClientMock,
CalendarController sut)
{
// Arrange
var startDate = fixture.Create<DateTimeOffset>();
var endDate = fixture.Create<DateTimeOffset>();
var result = fixture.Build<EventList>()
.With(x => x.Events, fixture.CreateMany<Event>(5).ToList())
.Create();
// override client mock setup:
calendarServiceClientMock.Setup(m => m.GetEvents(It.IsAny<DateTime>(), It.IsAny<DateTime>(), It.IsAny<CancellationToken>()))
.ReturnsAsync(fixture.Build<EventList>()
.With(x => x.Events, fixture.CreateMany<Event>(5).ToList())
.Create()).Verifiable();
// Act
var eventList = await sut.GetAllEvents(startDate, endDate);
// Assert
eventList.Events.Count.Should().Be(5); // FAILS - IT GETS 3 AND NOT 5
calendarServiceClientMock.Verify(); // THIS FAILS TOO IF I SET 3 IN ABOVE
}
I have tried with and without the Frozen attribute.
What am I missing here? I don't want to call my calendarcontroller builder as the point is to avoid boilerplate. Do I need a registration of the client or something else I'm missing
(maybe related to Override Autofixture customization setup but using moq and not n-subtitute. Could not get this to work even with correct order of parameters)
Thanks for reading!