簡體   English   中英

AutoFixture AutoMoq不為某些屬性創建模擬

[英]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覆蓋。

因此,即使您切換到AutoConfiguredMoqCustomizationLogger屬性仍然為null ,因為它是只讀的。 另一方面,具有返回值的其他屬性和方法將配置為返回由AutoFixture創建的對象。

您現在最好的選擇是開始使用AutoConfiguredMoqCustomization並降級到早期版本的Moq ,其中只讀屬性仍在正確配置中。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM