简体   繁体   中英

Moq - Setup Method with Expression of anonymous type

I have a function with this signature -

TSelect Get<TSelect>(int id, Expression<Func<T, TSelect>> select);

T is declared on the class level. It's meant to allow developers to pass in the shape they wish the object to be returned as, like .Select in Linq.

So it's usage looks like

_query.Get(123, x => new { x.Id, x.Name })

I cannot figure out how to set this up in Moq. I've seen a lot of answers about using It.IsAnyType , but that doesn't seem to work in an expression. And Moq doesn't match anonymous types to objects by design, so Expression<Func<MyType, object>> doesn't work.

Any Ideas?

If your goal is to mock for a select function that returns an instance of an anonymous type, you could achieve this by a helper function:

public class MyUnitTest
{
    [Fact]
    public void Test()
    {
        var query = CreateMockQuery(
            new Person { Name = "Bob" },
            new { Id = default(int), Name = default(string) } // Declares the anonymous type
        );

        var result = query.Get(5, p => new { Id = 5, p.Name });
        Assert.Equal("Bob", result.Name);
    }

    private IQuery<T> CreateMockQuery<T, TSelect>(
        T source,
        TSelect _ /* captures the anonymous type*/)
    {
        var mockQuery = new Mock<IQuery<T>>();
        mockQuery
            .Setup(x => x.Get(It.IsAny<int>(), It.IsAny<Expression<Func<T, TSelect>>>()))
            .Returns(
                (int id, Expression<Func<T, TSelect>> select)
                    => select.Compile()(source));
        return mockQuery.Object;
    }
}

public class Person
{
    public string Name { get; set; }
}

public interface IQuery<T>
{
    TSelect Get<TSelect>(int id, Expression<Func<T, TSelect>> select);
}

To avoid passing an anonymous type as a generic type argument, we can pass it as the input to CreateMockQuery so the compiler could automatically detect the type.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM