c# -验证模拟(MoQ)属性'的方法被调用的部分字符串作为参数

本文关键字:调用 方法 字符串 参数 模拟 验证 MoQ 属性 | 更新日期: 2023-09-27 18:04:45

我正在使用MoQ和c#来模拟公共属性,我想知道是否有一个模拟的方法是用任何以特定字符集开头的字符串调用的。

例如,虽然我知道这是有效的:

mockLogger.Verify(x => x.Information($"Entering {methodName}"), Times.Once);

我正在尝试,通过下面的尝试,看看mockLoggerInformation()方法是否用以$"Exception in {methodName} - Error Message: {ex.Message} - StackTrace:"

开头的参数调用
mockLogger.Verify(x => x.Information($"Exception in {methodName}: " +
                                         $"Error Message: {exceptionMessage} - " +
                                         $"StackTrace: ........"), Times.Once);

这难道不可能吗?或者有什么变通的办法?

编辑:

我甚至试过

    mockLogger.Verify(x => x.Information($"Exception in {methodName}: " +
                                         $"Error Message: {exceptionMessage} - " +
                                         $"StackTrace: " + It.IsAny<string>()), 
                                         Times.Once);

但是它似乎也不起作用

c# -验证模拟(MoQ)属性'的方法被调用的部分字符串作为参数

您也可以使用It.Is<string>(),它可以执行比较。

string searchString = $"Exception in {methodName}: " +
                      $"Error Message: {exceptionMessage} - " +
                      $"StackTrace: ";
mockLogger.Verify(x => x.Information(It.Is<string>(s => s.StartsWith(searchString))), Times.Once);

这可能比我之前建议的使用It.IsRegex()更清晰。

您不必在验证中检查精确匹配,您可以查找字符串的一部分,例如:

mockLogger.Verify(x => x.Information.IndexOf($"Exception in {methodName}:") >= 0 && x.Information.IndexOf($"Error Message: {exceptionMessage} - ") >= 0 && x.Information.IndexOf($"StackTrace: ") >= 0), Times.Once);

您可以使用Regex来完成此操作。字符串可以与以regex为参数的It.IsRegex()方法进行比较。

例如

string regexString = "" //Substitute for actual regex to search what you want
mockLogger.Verify(x => x.Information(It.IsRegex(regexString)), Times.Once);

以下代码示例来自Moq的快速入门,显示了它在设置中使用,但它也可以在验证中工作:

// matching regex
mock.Setup(x => x.DoSomething(It.IsRegex("[a-d]+", RegexOptions.IgnoreCase))).Returns("foo");

另一种可能是使用Callback方法。Callback方法可以接收用于调用模拟方法的参数,因此可以做任何您需要的自定义验证。例子:

[TestMethod]
public void VerifyWithCallback()
{
    // Arrange
    bool startsWith = false;
    const string methodName = "methodName";
    Mock<ILogger> mockLogger = new Mock<ILogger>();
    SomeClassWithLogger cut = new SomeClassWithLogger { Logger = mockLogger.Object };
    mockLogger.Setup(l => l.Information(It.IsAny<string>())).Callback<string>(s =>
    {
        startsWith = s.StartsWith("Entering starts with test");
    });
    // Act
    cut.Logger.Information($"Entering starts with test {methodName}");
    // Assert
    Assert.IsTrue(startsWith);
}

我相信moq文档在验证属性时使用了VerifySet()方法。看看这里:https://github.com/Moq/moq4/wiki/Quickstart