C# - 验证模拟 (MoQ) 属性 的方法是使用字符串的一部分作为参数调用的
C# - Verify mocked (MoQ) property's method was called with part of string as a parameter
我正在使用 MoQ 和 C# 来模拟 public 属性,我想知道是否使用以特定字符集开头的任何字符串调用了模拟方法之一。
例如,虽然我知道这行得通:
mockLogger.Verify(x => x.Information($"Entering {methodName}"), Times.Once);
我正在尝试通过以下尝试查看是否使用以 $"Exception in {methodName} - Error Message: {ex.Message} - StackTrace:"
开头的参数调用了 mockLogger
的 Information()
方法
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);
不过好像也没用。
我相信最小起订量文档在验证属性时使用了 VerifySet() 方法。看看这里:https://github.com/Moq/moq4/wiki/Quickstart
您不必在验证中检查是否完全匹配,您可以查找字符串的一部分,例如:
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 来执行此操作。字符串可以用 It.IsRegex()
方法进行比较,该方法将正则表达式作为参数。
一个例子是
string regexString = "" //Substitute for actual regex to search what you want
mockLogger.Verify(x => x.Information(It.IsRegex(regexString)), Times.Once);
来自 Moq quickstart 的以下代码示例显示它在设置中使用,但它也适用于 Verify:
// matching regex
mock.Setup(x => x.DoSomething(It.IsRegex("[a-d]+", RegexOptions.IgnoreCase))).Returns("foo");
您也可以只使用 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()
清楚得多。
另一种可能是使用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 和 C# 来模拟 public 属性,我想知道是否使用以特定字符集开头的任何字符串调用了模拟方法之一。
例如,虽然我知道这行得通:
mockLogger.Verify(x => x.Information($"Entering {methodName}"), Times.Once);
我正在尝试通过以下尝试查看是否使用以 $"Exception in {methodName} - Error Message: {ex.Message} - StackTrace:"
mockLogger
的 Information()
方法
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);
不过好像也没用。
我相信最小起订量文档在验证属性时使用了 VerifySet() 方法。看看这里:https://github.com/Moq/moq4/wiki/Quickstart
您不必在验证中检查是否完全匹配,您可以查找字符串的一部分,例如:
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 来执行此操作。字符串可以用 It.IsRegex()
方法进行比较,该方法将正则表达式作为参数。
一个例子是
string regexString = "" //Substitute for actual regex to search what you want
mockLogger.Verify(x => x.Information(It.IsRegex(regexString)), Times.Once);
来自 Moq quickstart 的以下代码示例显示它在设置中使用,但它也适用于 Verify:
// matching regex
mock.Setup(x => x.DoSomething(It.IsRegex("[a-d]+", RegexOptions.IgnoreCase))).Returns("foo");
您也可以只使用 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()
清楚得多。
另一种可能是使用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);
}