[英]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.