Moq一个具有匿名类型的函数 [英] Moq a function with anonymous type

查看:83
本文介绍了Moq一个具有匿名类型的函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试模拟此方法

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆