簡體   English   中英

如何為插值字符串設置模擬?

[英]How to setup a mock for an interpolated string?

假設我有一個記錄器接口實現,其上有一個Trace方法,如下所示:

public interface IMyLogger
{
    void Trace(string message, params object[] parameters);
}

public class MyLogger : IMyLogger
{
    public void Trace(string message, params object[] parameters)
    {
        // Writes the trace to a log file somewhere
    }
}

並且使用此記錄器調用的方法調用使用插值字符串,如下所示:

public class MyWorker
{
    private IMyLogger Logger { get; set; }

    public MyWorker(IMyLogger logger)
    {
        Logger = logger;
    }

    public void DoSomeWork(int x)
    {
        Logger.Trace($"Value of x is {x}");
    }
}

我正在為DoSomeWork方法編寫單元測試。 這就是我現在所擁有的,測試通過:

[TestMethod]
public void DoSomeWork_ShouldLogTrace()
{
    var mockLogger = new Mock<IMyLogger>(MockBehavior.Strict);
    mockLogger.Setup(l => l.Trace("Value of x is 5", It.IsAny<object[]>());

    var testWorker = new MyWorker();
    testWorker.DoSomeWork(5);
}

我的問題是:有沒有辦法可以將插值字符串傳遞給Trace設置而不是字符串插值的結果?

有沒有辦法可以將插值字符串傳遞給Trace設置而不是字符串插值的結果?

C#插值字符串不是模板引擎,而是編譯時功能。

這條線

Logger.Trace($"Value of x is {x}");

將使用格式化的消息調用Trace方法,而不使用參數。

因此,使用經典占位符或使用記錄器引擎,它處理模板參數,如Serilog

您不能傳遞插值字符串,但可以驗證是否使用您期望的值調用了Trace方法。

[TestMethod]
public void DoSomeWork_ShouldLogWarning()
{
    var mockLogger = new Mock<IMyLogger>(MockBehavior.Strict);
    mockLogger.Setup(l => l.Trace(It.IsAny<string>(), It.IsAny<object[]>()));

    var testWorker = new MyWorker(mockLogger.Object);

    const int expectedValue = 5;

    testWorker.DoSomeWork(expectedValue);

    mockLogger.Verify(x => x.Trace($"Value of x is {expectedValue}"));
}

在命名空間System使用FormattableString類型

也就是說,如果你有一個過載:

void Trace(FormattableString formattableMessage);

並確保使用它,然后像這樣的調用:

Logger.Trace($"Value of x is {x}");

會產生一個“富”的對象,你可以檢查.Format.GetArguments等。

解釋是編譯時表達式$" ... "可以隱式轉換為特殊類型FormattableString ,它不會立即“插入”,而是跟蹤格式和每個參數。 在實現中// Writes the trace to a log file somewhere ,在此富對象上使用.ToString()以執行實際插值。

然后Moq設置類似於:

// using nice Strict mock
mockLogger.Setup(l => l.Trace(It.Is(
  (FormattableString x) => x.Format == "Value of x is {0}"
  )));

已編輯:必須在模擬設置中使用索引為0 {0} ,而不是{x}

暫無
暫無

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

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