簡體   English   中英

模擬基類保護屬性

[英]Mocking base class protected property

我目前正在創建一個Mock單元測試,用於測試類方法的LogManager Logger.Error()調用,如下所示。

public class Test : BaseClass
{
   public override void DoSomething(object value)
   {
      try
      { 
         if (value == null)
         {
             throw new Exception();
         }         
      }
      catch(exception ex)
      {
         Logger.Error("Exception raised!", ex);
      }
   }
}

我的類使用一個抽象基類,它具有ILog定義如下的屬性

public abstract class BaseClass
{
   protected ILog Logger => LogManager.GetLogger(GetType());
}

問題是如何模擬這個基類屬性Logger以便我可以測試Logger.Error()是否被引發?

這是我的單元測試

[Test]
public void PassingNullParamShouldRaiseError()
{
    // Arrange
    var mockLog = new Mock<ILog>();
    var sut = new Test();

    // Action
    sut.DoSomething(null);

    // Assert
    mockLog.Verify(x => x.Error("Exception raised!"), Times.Once());
}

如果使基本屬性為虛擬

public abstract class BaseClass {
   protected virtual ILog Logger => LogManager.GetLogger(GetType());
}

您現在可以使用可在測試時使用的模擬覆蓋該屬性

[Test]
public void PassingNullParamShouldRaiseError() {
    // Arrange
    var mockLog = new Mock<ILog>();

    var sut = new Mock<Test>() {
        CallBase = true //Important to be able to call base member
    };

    //override default behavior of protected logger
    sut.Protected()
        .Setup<ILog>("Logger")
        .Returns(mockLog.Object);

    // Act
    sut.Object.DoSomething(null);

    // Assert
    mockLog.Verify(x => x.Error("Exception raised!", It.IsAny<Exception>()), Times.Once());
}

理想情況下,您的基類不應該與當前使用LogManager靜態實現問題緊密耦合

應該將記錄器顯式注入依賴類。 或至少通過日志工廠抽象,

public interface ILoggerFactory {
    ILog GetLogger(Type type);
}

其實現可以包裝代碼的味道

public class DefaultLoggerFactory : ILoggerFactory {
    public ILog GetLogger(Type type) => LogManager.GetLogger(type);
}

這可以用來獲得所需的日志

public class Test  {
    private readonly ILog logger;

    public Test(ILoggerFactory logs)  {
        logger = logs.GetLogger(GetType());
    }

    public void DoSomething(object value) {
        try {
            if (value == null) {
                throw new Exception();
            }
        } catch (Exception ex) {
            logger.Error("Exception raised!", ex);
        }
    }
}

暫無
暫無

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

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