Moq一个具有匿名类型的函数 [英] Moq a function with anonymous type
问题描述
我正在尝试模拟此方法
Task<TResult> GetResultAsync<TResult>(Func<string, TResult> transformFunc)
像这样
iMock.Setup(m => m.GetResultAsync(It.IsAny<Func<string, object>>())).ReturnsAsync(new { isPair = false });
测试调用方法,将匿名类型传递给像这样的通用参数
The method to test doing the call passing an anonymous type to the generic parameter like this
instance.GetResultAsync(u => new {isPair = u == "something" }) //dont look at the function return because as generic could have diferent implementations in many case
Moq永远不会使我的GetResultAsync方法与发送的参数匹配.
Moq never matches my GetResultAsync method with the parameters sent.
我正在使用Moq 4
I'm using Moq 4
推荐答案
匿名类型会给您带来麻烦.您需要一个具体的类型才能使其正常工作.
The anonymous type is going to cause you problems. You need a concrete type for this to work.
以下示例在我进行更改时有效
The following example worked when I changed
instance.GetResultAsync(u => new {isPair = u == "something" })
到
instance.GetResultAsync(u => (object) new {isPair = u == "something" })
Moq无法匹配匿名类型,这就是为什么在调用时得到null
的原因.
Moq is unable to match the anonymous type and that is why you get null
when called.
[TestClass]
public class MoqUnitTest {
[TestMethod]
public async Task Moq_Function_With_Anonymous_Type() {
//Arrange
var expected = new { isPair = false };
var iMock = new Mock<IService>();
iMock.Setup(m => m.GetResultAsync(It.IsAny<Func<string, object>>()))
.ReturnsAsync(expected);
var consumer = new Consumer(iMock.Object);
//Act
var actual = await consumer.Act();
//Assert
Assert.AreEqual(expected, actual);
}
public interface IService {
Task<TResult> GetResultAsync<TResult>(Func<string, TResult> transformFunc);
}
public class Consumer {
private IService instance;
public Consumer(IService service) {
this.instance = service;
}
public async Task<object> Act() {
var result = await instance.GetResultAsync(u => (object)new { isPair = u == "something" });
return result;
}
}
}
如果调用GetResultAsync
的代码依赖于使用匿名类型,那么您尝试使用测试进行的操作将不适用于当前设置.您可能需要为该方法提供一个具体类型.
if the code calling the GetResultAsync
is dependent on using the anonymous type then what you are trying to do with your test wont work with your current setup. You would probably need to provide a concrete type to the method.
[TestClass]
public class MoqUnitTest {
[TestMethod]
public async Task Moq_Function_With_Concrete_Type() {
//Arrange
var expected = new ConcreteType { isPair = false };
var iMock = new Mock<IService>();
iMock.Setup(m => m.GetResultAsync(It.IsAny<Func<string, ConcreteType>>()))
.ReturnsAsync(expected);
var sut = new SystemUnderTest(iMock.Object);
//Act
var actual = await sut.MethodUnderTest();
//Assert
Assert.AreEqual(expected, actual);
}
class ConcreteType {
public bool isPair { get; set; }
}
public interface IService {
Task<TResult> GetResultAsync<TResult>(Func<string, TResult> transformFunc);
}
public class SystemUnderTest {
private IService instance;
public SystemUnderTest(IService service) {
this.instance = service;
}
public async Task<object> MethodUnderTest() {
var result = await instance.GetResultAsync(u => new ConcreteType { isPair = u == "something" });
return result;
}
}
}
这篇关于Moq一个具有匿名类型的函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!