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.
Logger
property a concrete class? AutoMoq doesn't proxy concrete classes: blog.ploeh.dk/2010/08/25/… – PodolskMyService
has no other properties, but on the other hand, theService
class isn't described. Please provide a Short, Self Contained, Correct (Compilable), Example. – Podolsk