Pedram
Pedram

Reputation: 828

Unit testing - unexpected result from lambda expression in mock object

I am writing some unit tests. One of the tests I have written has unexpected behavior and I am confused about what has happened exactly. The problem is in mocking GetAsync method. When I use a variable like limit, the code does not work correctly, but if I use const instead of variables it works fine. Here is my source code:

namespace TestClass
{
    public class LambdaTest<T> where T : TestModel
    {
        readonly List<T> _list = new List<T>();
        public virtual IEnumerable<T> GetAsync(Expression<Func<T, bool>> predicate)
        {
            return _list.AsQueryable().Where(predicate).Where(x => !x.IsDeleted).ToList();
        }

        public IEnumerable<T> TestMethod()
        {
            int limit = 100;
            var result = GetAsync(p => !p.IsDeleted && (DateTime.Now - p.CreationDate).TotalHours < limit);
            return result;
        }
    }

    public class TestModel
    {
        public long Id { get; set; }
        public bool IsDeleted { get; set; }
        public DateTime CreationDate { get; set; }
    }
}

And the Test project:

namespace TestClass.Tests
{
    public class ExpressionTest
    {
        [Fact]
        public void SimpleTest()
        {
            var returnValue = new List<TestModel>
            {
                new TestModel() {CreationDate = DateTime.Now, Id = 1},
                new TestModel() {CreationDate = DateTime.Now, Id = 2}
            };
            var sut = new Mock<LambdaTest<TestModel>>();
            int limit = 100;
            sut.Setup(x => x.GetAsync(p => !p.IsDeleted && (DateTime.Now - p.CreationDate).TotalHours < limit))
               .Returns(returnValue);

            var result = sut.Object.TestMethod();

            Assert.True(true);
        }
    }
}

I can not use const here. I know about expression tree and some other subjects related to this problem, but can anyone explain what is happening exactly here and how can I solve this problem?

I will appreciate any help.

Upvotes: 1

Views: 741

Answers (1)

Pedram
Pedram

Reputation: 828

Finally, I solved the problem. I simulated the method behavior by something like this:

sut.Setup(x => x.GetAsync(
                It.IsAny<Expression<Func<TestModel, bool>>>()
            ))
            .Returns((Expression<Func<TestModel, bool>> predict) =>
            {
                var result = _list.Where(predict.Compile());
                return Task.FromResult(result);
            });

Upvotes: 1

Related Questions