C# Moq:获取表达式谓词的参数值
我不熟悉使用Moq,我正在尝试将值传递到Moq方法中,以便在Returns方法中使用 我成功地做到了以下几点C# Moq:获取表达式谓词的参数值,c#,unit-testing,moq,C#,Unit Testing,Moq,我不熟悉使用Moq,我正在尝试将值传递到Moq方法中,以便在Returns方法中使用 我成功地做到了以下几点 _repositoryMock.Setup(x => x.GetByOrderId(It.IsAny<string>())) .Returns((string id) => Task.FromResult( new Order {
_repositoryMock.Setup(x => x.GetByOrderId(It.IsAny<string>()))
.Returns((string id) => Task.FromResult(
new Order
{
Id = id
}));
上面的操作很好,传入Returns方法的id
与我在代码中传入GetByOrderId方法的id相同
但是,我希望使我的存储库更通用,因此我希望将GetByOrderId更改为FindFirstOrDefault,它采用表达式谓词而不是ID
用法如下:
var order = _repository.FindFirstOrDefault( o => x.Id == "123");
单元测试更改为:
_repositoryMock.Setup(moq => moq.FindFirst(It.IsAny<Expression<Func<Order, bool>>>()))
.Returns((Expression<Func<Order, bool>> expression) => Task.FromResult(
new Order
{
Id = // ... HOW TO GET ID LIKE THE FIRST SAMPLE?
}));
\u repositoryMock.Setup(moq=>moq.FindFirst(It.IsAny()))
.Returns((表达式)=>Task.FromResult(
新秩序
{
Id=/…如何像第一个样本一样获取Id?
}));
那我怎么才能拿到那个身份证呢?“123”。有什么办法吗?我找到了一份工作
我只是建立了一个Order
列表,其中包含我所知道的所有值,这些值都将出现在我的预期结果中,然后我将表达式应用到该列表以获得我想要的项
var expected = // INIT MY EXPECTED
List<Order> orders = new List<Order>();
foreach (var expectedItem in expected.Items)
{
orders.Add(new Order
{
Id = expectedItem.Id,
});
}
var expected=//INIT MY expected
列表顺序=新列表();
foreach(expected.Items中的var expectedItem)
{
订单。添加(新订单)
{
Id=expectedItem.Id,
});
}
然后我像这样设置我的模拟
_finicityRepositoryMock.Setup(moq => moq.FindFirst(It.IsAny<Expression<Func<Order, bool>>>()))
.Returns((Expression<Func<Order, bool>> expression) =>
{
var order = orders.AsQueryable().Where(expression).FirstOrDefault();
if (order == null)
{
return Task.FromResult((Order)null);
}
return Task.FromResult(
new Order
{
BorrowerID = order.Id
});
});
\u finicityRepositoryMock.Setup(moq=>moq.FindFirst(It.IsAny()))
.Returns((表达式)=>
{
var order=orders.AsQueryable().Where(表达式).FirstOrDefault();
if(order==null)
{
返回Task.FromResult((订单)空);
}
返回Task.FromResult(
新秩序
{
BorrowerID=order.Id
});
});
我找到了一个解决办法
我只是建立了一个Order
列表,其中包含我所知道的所有值,这些值都将出现在我的预期结果中,然后我将表达式应用到该列表以获得我想要的项
var expected = // INIT MY EXPECTED
List<Order> orders = new List<Order>();
foreach (var expectedItem in expected.Items)
{
orders.Add(new Order
{
Id = expectedItem.Id,
});
}
var expected=//INIT MY expected
列表顺序=新列表();
foreach(expected.Items中的var expectedItem)
{
订单。添加(新订单)
{
Id=expectedItem.Id,
});
}
然后我像这样设置我的模拟
_finicityRepositoryMock.Setup(moq => moq.FindFirst(It.IsAny<Expression<Func<Order, bool>>>()))
.Returns((Expression<Func<Order, bool>> expression) =>
{
var order = orders.AsQueryable().Where(expression).FirstOrDefault();
if (order == null)
{
return Task.FromResult((Order)null);
}
return Task.FromResult(
new Order
{
BorrowerID = order.Id
});
});
\u finicityRepositoryMock.Setup(moq=>moq.FindFirst(It.IsAny()))
.Returns((表达式)=>
{
var order=orders.AsQueryable().Where(表达式).FirstOrDefault();
if(order==null)
{
返回Task.FromResult((订单)空);
}
返回Task.FromResult(
新秩序
{
BorrowerID=order.Id
});
});
您可以分析表达式
如果您只在谓词表达式中执行x=>x.Id==“123”
,则解决方案可能非常简单:
mock.Setup(x => x.FindFirstOrDefault(It.IsAny<Expression<Func<Order, bool>>>()))
.Returns<Expression<Func<Order, bool>>>(
predicate =>
{
var id = (string)((ConstantExpression)(((BinaryExpression)predicate.Body).Right)).Value;
return new Order { Id = id };
});
然后将是:
mock.Setup(x => x.FindFirstOrDefault(It.IsAny<Expression<Func<Order, bool>>>()))
.Returns<Expression<Func<Order, bool>>>(
predicate =>
{
var visitor = new PredicatePropertyValueExpressionVisitor();
visitor.Visit(predicate);
return new Order { Id = visitor.PropertyValues["Id"].ToString() };
});
mock.Setup(x=>x.FindFirstOrDefault(It.IsAny()))
.返回(
谓词=>
{
var visitor=新谓词PropertyValueExpressionVisitor();
visitor.Visit(谓词);
返回新订单{Id=visitor.propertyValue[“Id”].ToString()};
});
您可以分析表达式
如果您只在谓词表达式中执行x=>x.Id==“123”
,则解决方案可能非常简单:
mock.Setup(x => x.FindFirstOrDefault(It.IsAny<Expression<Func<Order, bool>>>()))
.Returns<Expression<Func<Order, bool>>>(
predicate =>
{
var id = (string)((ConstantExpression)(((BinaryExpression)predicate.Body).Right)).Value;
return new Order { Id = id };
});
然后将是:
mock.Setup(x => x.FindFirstOrDefault(It.IsAny<Expression<Func<Order, bool>>>()))
.Returns<Expression<Func<Order, bool>>>(
predicate =>
{
var visitor = new PredicatePropertyValueExpressionVisitor();
visitor.Visit(predicate);
return new Order { Id = visitor.PropertyValues["Id"].ToString() };
});
mock.Setup(x=>x.FindFirstOrDefault(It.IsAny()))
.返回(
谓词=>
{
var visitor=新谓词PropertyValueExpressionVisitor();
visitor.Visit(谓词);
返回新订单{Id=visitor.propertyValue[“Id”].ToString()};
});