单元测试 - 模拟对象中 lambda 表达式的意外结果
Unit testing - unexpected result from lambda expression in mock object
我正在写一些单元测试。我编写的其中一个测试出现了意外行为,我对到底发生了什么感到困惑。问题在于模拟 GetAsync
方法。当我使用像 limit
这样的变量时,代码无法正常工作,但如果我使用 const 而不是变量,它就可以正常工作。这是我的源代码:
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; }
}
}
和测试项目:
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);
}
}
}
我不能在这里使用常量。我知道表达式树和其他一些与此问题相关的主题,但是谁能解释一下这里到底发生了什么以及我该如何解决这个问题?
如有任何帮助,我将不胜感激。
终于,我解决了这个问题。我通过这样的方式模拟了方法行为:
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);
});
我正在写一些单元测试。我编写的其中一个测试出现了意外行为,我对到底发生了什么感到困惑。问题在于模拟 GetAsync
方法。当我使用像 limit
这样的变量时,代码无法正常工作,但如果我使用 const 而不是变量,它就可以正常工作。这是我的源代码:
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; }
}
}
和测试项目:
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);
}
}
}
我不能在这里使用常量。我知道表达式树和其他一些与此问题相关的主题,但是谁能解释一下这里到底发生了什么以及我该如何解决这个问题?
如有任何帮助,我将不胜感激。
终于,我解决了这个问题。我通过这样的方式模拟了方法行为:
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);
});