无法验证 Moq'd Func 是否被调用
Cannot verify a Moq'd Func is invoked
我正在尝试使用 Moq 模拟 Func<Tin, Tout>
并验证它是否被调用(调用)
我目前的代码是:
var handlers = new List<ICallBridgeHandler>();
var stationIdReader = new Mock<IStationIdReader>();
var loggerCreator = new Mock<Func<Type, ILogger>>();
loggerCreator.Setup(x => x.Invoke(typeof(Service))).Returns<ILogger>(null);
loggerCreator.Verify(x => x.Invoke(It.IsAny<Type>()), Times.Never);
var sut = new Service(stationIdReader.Object, handlers, loggerCreator.Object);
loggerCreator.Verify(x => x.Invoke(typeof(Service)), Times.Once);
Assert.IsNotNull(sut);
但这正在爆炸,但有一个例外:
Result StackTrace:
at Moq.ExpressionExtensions.GetCallInfo(LambdaExpression expression, Mock mock)
at Moq.Mock.<>c__DisplayClass1c`2.<Setup>b__1b()
at Moq.PexProtector.Invoke[T](Func`1 function)
at Moq.Mock.Setup[T,TResult](Mock`1 mock, Expression`1 expression, Condition condition)
at Moq.Mock`1.Setup[TResult](Expression`1 expression)
at Tests.ConstructorRetrievesLoggerFromCreator() in ...
Result Message:
Test method Tests.ConstructorRetrievesLoggerFromCreator threw exception:
System.InvalidCastException: Unable to cast object of type
'System.Linq.Expressions.InstanceMethodCallExpressionN' to type
'System.Linq.Expressions.InvocationExpression'.
谁能帮忙解决这个问题,我需要能够检查构造函数是否调用了 Func。
N.B。我试图删除设置步骤,因为我不关心此测试的 return 值,并且我在 Verify 调用中遇到了同样的问题。
显然我可以注入一个 return 给定值的具体 Func 并以某种方式询问该值,但是我的服务 class 看起来像:
public class Service
{
private readonly ILogger _logger;
[ImportingConstructor]
public Service([Import("GetLogger")]Func<Type, ILogger> loggerCreator)
{
if (loggerCreator == null)
throw new ArgumentNullException(nameof(loggerCreator));
_logger = loggerCreator.Invoke(GetType());
}
}
所以不改变我的class我看不到成员变量_logger
所以我没有办法验证loggerCreator
已经被调用,这就是我想要验证的.
无需模拟函数。创建一个 Func
变量并在其中保留一个计数器以进行跟踪。
[TestMethod]
public void Func_Should_Be_Invoked_Once() {
//Arrange
var handlers = new List<ICallBridgeHandler>();
var stationIdReader = new Mock<IStationIdReader>();
var mockLogger = new Mock<ILogger>();
int loggerCreaterInvokeCalls = 0;
Func<Type, ILogger> loggerCreator = (type) => {
loggerCreaterInvokeCalls++;
return mockLogger.Object;
};
//Act
var sut = new Service(stationIdReader.Object, handlers, loggerCreator);
//Assert
Assert.IsNotNull(sut);
Assert.AreEqual(1, loggerCreaterInvokeCalls);
}
参考:Using Moq to Mock a Func<> constructor parameter and Verify it was called twice
我正在尝试使用 Moq 模拟 Func<Tin, Tout>
并验证它是否被调用(调用)
我目前的代码是:
var handlers = new List<ICallBridgeHandler>();
var stationIdReader = new Mock<IStationIdReader>();
var loggerCreator = new Mock<Func<Type, ILogger>>();
loggerCreator.Setup(x => x.Invoke(typeof(Service))).Returns<ILogger>(null);
loggerCreator.Verify(x => x.Invoke(It.IsAny<Type>()), Times.Never);
var sut = new Service(stationIdReader.Object, handlers, loggerCreator.Object);
loggerCreator.Verify(x => x.Invoke(typeof(Service)), Times.Once);
Assert.IsNotNull(sut);
但这正在爆炸,但有一个例外:
Result StackTrace:
at Moq.ExpressionExtensions.GetCallInfo(LambdaExpression expression, Mock mock)
at Moq.Mock.<>c__DisplayClass1c`2.<Setup>b__1b()
at Moq.PexProtector.Invoke[T](Func`1 function)
at Moq.Mock.Setup[T,TResult](Mock`1 mock, Expression`1 expression, Condition condition)
at Moq.Mock`1.Setup[TResult](Expression`1 expression)
at Tests.ConstructorRetrievesLoggerFromCreator() in ...
Result Message:
Test method Tests.ConstructorRetrievesLoggerFromCreator threw exception:
System.InvalidCastException: Unable to cast object of type
'System.Linq.Expressions.InstanceMethodCallExpressionN' to type
'System.Linq.Expressions.InvocationExpression'.
谁能帮忙解决这个问题,我需要能够检查构造函数是否调用了 Func。
N.B。我试图删除设置步骤,因为我不关心此测试的 return 值,并且我在 Verify 调用中遇到了同样的问题。
显然我可以注入一个 return 给定值的具体 Func 并以某种方式询问该值,但是我的服务 class 看起来像:
public class Service
{
private readonly ILogger _logger;
[ImportingConstructor]
public Service([Import("GetLogger")]Func<Type, ILogger> loggerCreator)
{
if (loggerCreator == null)
throw new ArgumentNullException(nameof(loggerCreator));
_logger = loggerCreator.Invoke(GetType());
}
}
所以不改变我的class我看不到成员变量_logger
所以我没有办法验证loggerCreator
已经被调用,这就是我想要验证的.
无需模拟函数。创建一个 Func
变量并在其中保留一个计数器以进行跟踪。
[TestMethod]
public void Func_Should_Be_Invoked_Once() {
//Arrange
var handlers = new List<ICallBridgeHandler>();
var stationIdReader = new Mock<IStationIdReader>();
var mockLogger = new Mock<ILogger>();
int loggerCreaterInvokeCalls = 0;
Func<Type, ILogger> loggerCreator = (type) => {
loggerCreaterInvokeCalls++;
return mockLogger.Object;
};
//Act
var sut = new Service(stationIdReader.Object, handlers, loggerCreator);
//Assert
Assert.IsNotNull(sut);
Assert.AreEqual(1, loggerCreaterInvokeCalls);
}
参考:Using Moq to Mock a Func<> constructor parameter and Verify it was called twice