RND*_*hts 4 c# dependency-injection moq autofixture automoq
我正在使用AutoFixture AutoMoqCustomization
并尝试创建一个包含readonly属性的类的实例,因此:
public override ILog Logger { get; } = LogManager.GetLogger(typeof(MyService));
Run Code Online (Sandbox Code Playgroud)
这个想法是我应该能够ILog
使用以下方法冻结我的测试测试:
var log = fixture.Freeze<Mock<ILog>>;
Run Code Online (Sandbox Code Playgroud)
并验证它在主方法调用之后被调用:
log.Verify(l => l.Warn, Times.Once);
Run Code Online (Sandbox Code Playgroud)
但是,当我调用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);
}
Run Code Online (Sandbox Code Playgroud)
我还验证了手动创建Mocks并使用Moq设置它们 - 该ILog
属性已被我的Mock正确替换使用:
myServiceMock.Setup(s => s.Logger).Returns(myLoggerMock)
Run Code Online (Sandbox Code Playgroud)
任何人都可以对此有所了解吗?
重现步骤
测试
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());
}
Run Code Online (Sandbox Code Playgroud)
服务等级 - 注意:通常该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; }
}
}
Run Code Online (Sandbox Code Playgroud)
如果您在该service.Post(null)
行上断点,您将看到该ILog
属性仍为null,但其他属性具有模拟.
所有这些AutoMoqCustomization
都是配置AutoFixture将所有接口或抽象类型的请求委托给Moq.它不会自动为创建的测试双打的属性和方法设置任何存根.
然而,由于AutoFixture 3.20.0有一个新的自动嘲讽定制所做的正是这-的AutoConfiguredMoqCustomization
:
var fixture = new Fixture().Customize(new AutoConfiguredMoqCustomization());
Run Code Online (Sandbox Code Playgroud)
启用该自定义可确保Moq中出现的Test Doubles配置为返回AutoFixture从其所有公共属性创建的对象.
但是有一个问题.正如@dcastro所报告的那样,Moq 4.2.1502.911中引入了一个错误,该错误导致只读属性(如MyService.Logger
您的情况下的属性)在AutoFixture配置后被Moq覆盖.
所以,即使你切换到AutoConfiguredMoqCustomization
该Logger
属性将仍然为空凭借它被只读的.另一方面,具有返回值的其他属性和方法将配置为返回由AutoFixture创建的对象.
您现在最好的选择是开始使用AutoConfiguredMoqCustomization
和降级到早期版本的Moq,其中只读属性仍在正确配置中.
归档时间: |
|
查看次数: |
1653 次 |
最近记录: |