使用 Moq 无法验证带有默认参数的模拟呼叫
Using Moq Unable to Verify Mocked Call With Default Parameters
无论我将设置设置得多么一般,尝试调用 Mocked 依赖项的验证总是失败。
这是我希望模拟的接口上的方法签名:
Task EnqueueAsync<T>(string factoryId, string clientId, T messageObject, string messageId = null, string messageLabel = null, bool forcePersistence = true, DateTime? scheduledEnqueueTimeUtc = null, Dictionary<string, object> properties = null, double retryTime = 0);
这是我的设置方法:
mockTopic = new Mock<ITopic>();
mockTopic.Setup(m => m.EnqueueAsync(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<bool>(), It.IsAny<DateTime?>(), It.IsAny<Dictionary<string, object>>(), It.IsAny<double>()))
.Callback((string factoryId, string clientId, string messageObject, string messageId, string messageLabel, bool forcePersistence, DateTime? scheduledEnqueueTimeUtc, Dictionary<string, object> properties, double retryTime) =>
{
testProperties = properties;
testMessageId = messageId;
});
这是我的验证电话:
mockTopic.Verify(m => m.EnqueueAsync(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<bool>(), It.IsAny<DateTime?>(), It.IsAny<Dictionary<string, object>>(), It.IsAny<double>()));
这是验证方法抛出的错误消息:
Moq.MockException :
Expected invocation on the mock once, but was 0 times: m => m.EnqueueAsync<string>(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<bool>(), It.IsAny<DateTime?>(), It.IsAny<Dictionary<string, object>>(), It.IsAny<double>())
Performed invocations:
Mock<ITopic:1> (m):
IServiceBus<TopicClient>.EnqueueAsync<object>(null, null, "", "c0fa2b2a-fcb7-4252-964e-cecf97bbeeb9", null, True, null, Dictionary<string, object>, 1)
查看将验证定义与调用进行比较的消息,我发现调用之间没有区别。我对此束手无策。
您可以为此使用 It.IsAnyType
:
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Moq;
namespace ConsoleApp24
{
class Program
{
static void Main(string[] args)
{
var mock = new Mock<ITopic>();
var ensureAsyncSetup = mock.Setup(m => m.EnqueueAsync(
It.IsAny<string>(),
It.IsAny<string>(),
// By using It.IsAnyType the matcher will work for all T
It.Is<It.IsAnyType>((v, _) => true),
It.IsAny<string>(),
It.IsAny<string>(),
It.IsAny<bool>(),
It.IsAny<DateTime?>(),
It.IsAny <Dictionary<string, object>>(),
It.IsAny<double>()));
ensureAsyncSetup.Callback((string factoryId, string clientId, object messageObject, string messageId,
string messageLabel, bool forcePersistence, DateTime? scheduledEnqueueTimeUtc,
Dictionary<string, object> properties, double retryTime) =>
{
Console.WriteLine("This will run");
});
// Setup call as verifiable
ensureAsyncSetup.Verifiable();
mock.Object.EnqueueAsync(null, null, "", "c0fa2b2a-fcb7-4252-964e-cecf97bbeeb9", null, true, null, new Dictionary<string, object>(), 1);
// This will pass as the method is called once
mock.Verify();
}
}
public interface ITopic
{
Task EnqueueAsync<T>(string factoryId, string clientId, T messageObject, string messageId = null, string messageLabel = null, bool forcePersistence = true, DateTime? scheduledEnqueueTimeUtc = null, Dictionary<string, object> properties = null, double retryTime = 0);
}
}
无论我将设置设置得多么一般,尝试调用 Mocked 依赖项的验证总是失败。
这是我希望模拟的接口上的方法签名:
Task EnqueueAsync<T>(string factoryId, string clientId, T messageObject, string messageId = null, string messageLabel = null, bool forcePersistence = true, DateTime? scheduledEnqueueTimeUtc = null, Dictionary<string, object> properties = null, double retryTime = 0);
这是我的设置方法:
mockTopic = new Mock<ITopic>();
mockTopic.Setup(m => m.EnqueueAsync(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<bool>(), It.IsAny<DateTime?>(), It.IsAny<Dictionary<string, object>>(), It.IsAny<double>()))
.Callback((string factoryId, string clientId, string messageObject, string messageId, string messageLabel, bool forcePersistence, DateTime? scheduledEnqueueTimeUtc, Dictionary<string, object> properties, double retryTime) =>
{
testProperties = properties;
testMessageId = messageId;
});
这是我的验证电话:
mockTopic.Verify(m => m.EnqueueAsync(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<bool>(), It.IsAny<DateTime?>(), It.IsAny<Dictionary<string, object>>(), It.IsAny<double>()));
这是验证方法抛出的错误消息:
Moq.MockException :
Expected invocation on the mock once, but was 0 times: m => m.EnqueueAsync<string>(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<bool>(), It.IsAny<DateTime?>(), It.IsAny<Dictionary<string, object>>(), It.IsAny<double>())
Performed invocations:
Mock<ITopic:1> (m):
IServiceBus<TopicClient>.EnqueueAsync<object>(null, null, "", "c0fa2b2a-fcb7-4252-964e-cecf97bbeeb9", null, True, null, Dictionary<string, object>, 1)
查看将验证定义与调用进行比较的消息,我发现调用之间没有区别。我对此束手无策。
您可以为此使用 It.IsAnyType
:
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Moq;
namespace ConsoleApp24
{
class Program
{
static void Main(string[] args)
{
var mock = new Mock<ITopic>();
var ensureAsyncSetup = mock.Setup(m => m.EnqueueAsync(
It.IsAny<string>(),
It.IsAny<string>(),
// By using It.IsAnyType the matcher will work for all T
It.Is<It.IsAnyType>((v, _) => true),
It.IsAny<string>(),
It.IsAny<string>(),
It.IsAny<bool>(),
It.IsAny<DateTime?>(),
It.IsAny <Dictionary<string, object>>(),
It.IsAny<double>()));
ensureAsyncSetup.Callback((string factoryId, string clientId, object messageObject, string messageId,
string messageLabel, bool forcePersistence, DateTime? scheduledEnqueueTimeUtc,
Dictionary<string, object> properties, double retryTime) =>
{
Console.WriteLine("This will run");
});
// Setup call as verifiable
ensureAsyncSetup.Verifiable();
mock.Object.EnqueueAsync(null, null, "", "c0fa2b2a-fcb7-4252-964e-cecf97bbeeb9", null, true, null, new Dictionary<string, object>(), 1);
// This will pass as the method is called once
mock.Verify();
}
}
public interface ITopic
{
Task EnqueueAsync<T>(string factoryId, string clientId, T messageObject, string messageId = null, string messageLabel = null, bool forcePersistence = true, DateTime? scheduledEnqueueTimeUtc = null, Dictionary<string, object> properties = null, double retryTime = 0);
}
}