Moq a function with anonymous type

后端 未结 1 1177
情书的邮戳
情书的邮戳 2020-12-20 21:52

I\'m trying to mock this method

Task GetResultAsync(Func transformFunc)

like this

相关标签:
1条回答
  • 2020-12-20 22:15

    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" })
    

    to

    instance.GetResultAsync(u => (object) new {isPair = u == "something" })
    

    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;
            }
        }
    }
    

    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;
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题