[英]AutoFixture AutoMoq not creating mocks for some properties
我正在使用AutoFixture與AutoMoqCustomization
並嘗試創建一個包含readonly屬性的類的實例,因此:
public override ILog Logger { get; } = LogManager.GetLogger(typeof(MyService));
這個想法是我應該能夠使用以下方法凍結我的測試ILog
測試:
var log = fixture.Freeze<Mock<ILog>>;
並驗證它在主方法調用之后被調用:
log.Verify(l => l.Warn, Times.Once);
但是,當我調用fixture.Create fixture.Create<MyService>
AutoFixture不會用模擬ILog
替換Logger
屬性。 我也嘗試刪除默認值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
屬性仍為null,但其他屬性都有模擬。
AutoMoqCustomization
所做的就是配置AutoFixture以將所有接口或抽象類型的請求委托給Moq。 它不會自動為創建的測試雙打的屬性和方法設置任何存根。
但是,從AutoFixture 3.20.0開始,有一個新的自動模擬自定義功能就是這樣 - AutoConfiguredMoqCustomization
:
var fixture = new Fixture().Customize(new AutoConfiguredMoqCustomization());
啟用該自定義可確保Moq中出現的Test Doubles配置為返回AutoFixture從其所有公共屬性創建的對象。
但是有一個問題。 正如@dcastro所報告的那樣 , Moq 4.2.1502.911中引入了一個錯誤,它導致只讀屬性 (如你的情況下的MyService.Logger
屬性)在AutoFixture配置后被Moq覆蓋。
因此,即使您切換到AutoConfiguredMoqCustomization
, Logger
屬性仍然為null ,因為它是只讀的。 另一方面,具有返回值的其他屬性和方法將配置為返回由AutoFixture創建的對象。
您現在最好的選擇是開始使用AutoConfiguredMoqCustomization
並降級到早期版本的Moq ,其中只讀屬性仍在正確配置中。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.