【问题标题】:Mocking (moq) a GetAllAsync linq query with select使用 select 模拟 (moq) GetAllAsync linq 查询
【发布时间】:2015-11-10 16:16:24
【问题描述】:

这是我需要模拟的特定代码行。

IGenericRepository<Foo> _fooRepository;
var listOfIds = await _fooRepository.GetAllAsync(o => o.Ids);

这是获取一个 int 列表来表示此数据表中的 ID。换句话说,

select Ids from Table

FooRepository 是通过 IGenericRepository 实现的,全部使用实体框架。基础表中的 Ids 字段只是整数值,我试图从中获取一个 int 列表。我不想要任何其他列。

所以我尝试了以下方法无济于事:

1.

_listOfIds = new List<int> {1,2,3,4,5};

_fooRepositoryMock.Setup(o => o.GetAllAsync(
It.IsAny<Expression<Func<Foo, bool>>>()))
.Returns((Expression<Func<Foo, bool>> Predicate) =>
Task.FromResult(_listOfids.Where(Predicate.Compile()).ToList() 
as ICollection<int>));

有了这个,IntelliSense 抱怨它无法从...进行转换

'System.Func<Foo, Bool> to System.Func<int, int, bool>"

我一开始尝试处理进出 Func 委托的不同类型。但我仍然遇到同样的错误。

2.

然后我尝试只使用默认值,因为我并不特别介意它是否完全测试该行。 ID 列表稍后将在该方法中使用。但我需要模拟它,因为如果它为 null,则会导致测试方法进一步失败。

_listOfids= new List<int> {1,2,3,4,5};
_fooRepositoryMock.SetReturnsDefault(_listOfIds);

由于某种原因,在调试时 listOfIds 仍然为空。

我有点坚持这个。我唯一能想到的就是将这行代码粘贴到辅助方法中,然后模拟辅助方法。但是为了通过测试而重写代码似乎是一种非常糟糕的方式。

【问题讨论】:

    标签: linq unit-testing automated-tests moq


    【解决方案1】:

    您不必为 Returns 方法调用指定参数。 Moq 还包括另一种设置异步方法结果的方法。

    _fooRepositoryMock.Setup(o => o.GetAllAsync(It.IsAny<Expression<Func<Foo, int>>>()))
                      .ReturnsAsync(idList);
    

    【讨论】:

    • 这实际上是我最初的尝试。这产生的错误是“方法的类型参数”ReturnsExtensions.ReturnsAsync(IReturns,TMock, Task>, TResult) 无法从用法中推断出来。尝试明确指定类型参数。这就是导致我首先尝试编译查询的原因
    • @JonSick 可以分享一下 GetAllAsync 方法的签名吗?
    • 当然。它的'Task> GetAllAsync(Expression> select);'
    • @JonSick Foo 类中的 Ids 属性的类型是什么?
    • VS 接受它,但由于某种原因,在运行调试测试时,真实方法中的 listOfIds 保持为空。编辑:修复它。出于某种原因,将其更改为可为空的 int 并更改模拟测试方法中的 _listOfIds 使其工作。去搞清楚!感谢负载的帮助!我在这个问题上卡得太久了。
    猜你喜欢
    • 2016-12-15
    • 2016-03-20
    • 2012-02-18
    • 1970-01-01
    • 2019-07-23
    • 2011-10-02
    • 1970-01-01
    • 1970-01-01
    • 2011-06-13
    相关资源
    最近更新 更多