我正试图模仿这种方法
Task<TResult> GetResultAsync<TResult>(Func<string, TResult> transformFunc)
像这样
iMock.Setup(m => m.GetResultAsync(It.IsAny<Func<string, object>>())).ReturnsAsync(new { isPair = false });
测试执行调用的方法将匿名类型传递给泛型参数,如
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 4
答案 0 :(得分:3)
匿名类型会给你带来麻烦。你需要一个具体的类型才能发挥作用。
以下示例在我更改时起作用
instance.GetResultAsync(u => new {isPair = u == "something" })
到
instance.GetResultAsync(u => (object) new {isPair = u == "something" })
Moq无法匹配匿名类型,这就是您在调用时获得null
的原因。
[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
的代码依赖于使用匿名类型,那么您尝试对测试执行的操作将不适用于您当前的设置。您可能需要为该方法提供具体类型。
[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;
}
}
}