【发布时间】:2015-10-15 16:36:16
【问题描述】:
我正在使用带有 AutoMoqCustomization 的 AutoFixture 并尝试创建一个包含只读属性的类的实例:
public override ILog Logger { get; } = LogManager.GetLogger(typeof(MyService));
我的想法是我应该能够冻结我的测试ILog test double 使用:
var log = fixture.Freeze<Mock<ILog>>;
并验证它是在 main 方法调用之后通过以下方式调用的:
log.Verify(l => l.Warn, Times.Once);
但是,当我调用 fixture.Create<MyService> 时,AutoFixture 不会将 Logger 属性替换为 ILog 的模拟。我还尝试删除默认值LogManager.GetLogger<etc>,在这种情况下ILog 的值是null。
其他属性正确填充了测试替身,但不是这个。
作为参考,ILog 接口来自 ServiceStack 的日志框架,如下所示:
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);
}
我还验证了手动创建 Mocks 并使用 Moq 进行设置 - ILog 属性已正确替换为我的 Mock 使用:
myServiceMock.Setup(s => s.Logger).Returns(myLoggerMock)
任何人都可以对此有所了解吗?
复制步骤
测试
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());
}
服务类 - 注意:通常Logger 属性会以= LogManager.GetLogger(typeof(MyService)) 为后缀,但我在此时省略了它以查看问题。
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; }
}
}
如果您在 service.Post(null) 行上设置断点,您将看到 ILog 属性仍然为空,但其他属性有模拟。
【问题讨论】:
-
具有
Logger属性的类是具体类吗? AutoMoq 不代理具体类:blog.ploeh.dk/2010/08/25/… -
嗨,马克,这是一个具体的类,所以我同意你的观点,但如果是这样的话,为什么 AutoMoq 会自动填充同一类的所有其他属性?
-
我不知道,因为你没有给我看复制品...
-
已添加重现步骤。
-
其他属性是什么意思?正如这里给出的,
MyService没有其他属性,但另一方面,Service类没有被描述。请提供Short, Self Contained, Correct (Compilable), Example。
标签: c# dependency-injection moq autofixture automoq