I am using AutoFixture with the AutoMoqCustomization and attempting to create an instance of a class which contains a readonly property thus:
public override ILog Logger { get; } = LogManager.GetLogger(typeof(MyService));
The idea being that i should be able to freeze my test ILog test double using:
var log = fixture.Freeze<Mock<ILog>>;
and verify it was called later after the main method invocation by:
log.Verify(l => l.Warn, Times.Once);
However, when i call fixture.Create<MyService> AutoFixture does not replace the Logger property with a mock of ILog. I have also tried removing the default value LogManager.GetLogger<etc> in which case the value of ILog is null.
Other properties are correctly populated with test doubles but not this one.
For reference, the ILog interface is from ServiceStack's logging framework and looks like this:
public interface ILog
{
bool IsDebugEnabled { get; }
void Debug(object message);
void Debug(object message, Exception exception);
void DebugFormat(string format, params object[] args);
void Error(object message);
void Error(object message, Exception exception);
void ErrorFormat(string format, params object[] args);
void Fatal(object message);
void Fatal(object message, Exception exception);
void FatalFormat(string format, params object[] args);
void Info(object message);
void Info(object message, Exception exception);
void InfoFormat(string format, params object[] args);
void Warn(object message);
void Warn(object message, Exception exception);
void WarnFormat(string format, params object[] args);
}
I have also verified that creating the Mocks manually and setting them up with Moq works - the ILog property is correctly replaced with my Mock using:
myServiceMock.Setup(s => s.Logger).Returns(myLoggerMock)
Can anyone shed any light on this?
Steps to Reproduce
Test
using ServiceStack;
using ServiceStack.Logging;
using ServiceStack.Web;
using MyApp;
[Test]
public void LogTest()
{
var fixture = new Fixture().Customize(new AutoMoqCustomization());
var log = fixture.Freeze<Mock<ILog>>();
var request = fixture.Freeze<Mock<IRequest>>();
var response = new Mock<IResponse>();
var service = fixture.Create<MyService>();
request.Setup(r => r.Response).Returns(response.Object);
service.Post(null);
log.Verify(l => l.Warn(It.IsAny<string>()), Times.Once());
}
Service Class - NB: Normally the Logger property would be suffixed = LogManager.GetLogger(typeof(MyService)) but i have omitted it at this point to see the issue.
using ServiceStack;
using ServiceStack.Logging;
namespace MyApp
{
public class MyService : BaseService
{
public override ILog Logger { get; }
public MyResponse Post(MyRequest request)
{
if (request != null) return new MyResponse() {Message = request.Message};
Logger.Warn("Null request object");
return null;
}
}
public abstract class BaseService : Service
{
public abstract ILog Logger { get; }
}
public class MyRequest
{
public string Message { get; set; }
}
public class MyResponse
{
public string Message { get; set; }
}
}
If you breakpoint on the service.Post(null) line you will see the ILog property is still null but other properties have mocks.