使用Moq </t,>使用Func <t,bool =“”>参数模拟存储库调用

时间:2013-09-26 15:53:50

标签: c# mocking moq

我正在尝试使用Moq模拟我的一些存储库调用,并且我生成的大多数单元测试都运行正常,但是我遇到的情况似乎无法正确模拟。

我需要模拟的存储库调用具有以下签名:

IEnumerable<T> Get(
    Expression<Func<T, bool>> filter = null, 
    Func<IQueryable<T>, IOrderedQueryable<T>> orderBy = null, 
    string includeProperties = "");

我单元测试的方法如下:

public bool CheckForTaskUsage(int taskId)
{
    return _taskInstanceRepository.Get(x => x.Task.Id == taskId).Any();
}

单元测试如下:

Task task_1 = new Task() { Id = 1 };
TaskInstance taskInstance_1 = new TaskInstance() { Id = 1, Task = task_1 };
_domainTaskInstances = new List<TaskInstance>() { taskInstance_1 };

[TestMethod()]
public void TaskService_CheckForTaskUsage_Success()
{
    int taskId = 1;
    //_taskInstanceRepository.Setup(x => x.Get(y => y.Task.Id == taskId,null,""))
    //    .Returns(_domainTaskInstances);
    _taskInstanceRepository.Setup(x => x.Get(null, null, ""))
        .Returns(_domainTaskInstances);
    bool expected = true;
    bool actual;
    actual = GetTarget().CheckForTaskUsage(taskId);
    Assert.AreEqual(expected, actual);
}

无论如何,测试失败,因为对CheckForTaskUsage的调用返回false,正如您在应用于Moq设置的_domainTaskInstances所看到的那样不正确。我已逐步完成代码,它应该正常工作,它可以通过UI按预期工作。

然后我尝试重新尝试重新创建Func<>方法中使用的CheckForTaskUsage(您可以在单元测试中看到此尝试被注释掉),再次失败,即使签名和变量应该是相同的。

最后,作为测试,我尝试将CheckForTaskUsage方法内容修改为以下内容:

return _taskInstanceRepository.Get().Where(x => x.Task.Id == taskId).Any();

这允许测试成功通过,但是我不想更改我的方法代码以允许单元测试通过!

我认为问题在于我需要重新创建Func<>参数,但我不知道我在这里做错了什么,任何建议都会受到欢迎!

由于

(ps我知道我没有这里的所有代码(例如一些变量声明等),但我知道这不是问题,因为代码用于其他测试和工作正常,这会使问题变得混乱。)

根据要求:

public TaskService GetTarget()
{
    return new TaskService(_taskRepository.Object);
}

1 个答案:

答案 0 :(得分:4)

我认为你应该这样做:

_taskInstanceRepository
    .Setup(x => x.Get(It.IsAny<Expression<Func<TaskInstance, bool>>>(), null, ""))
    .Returns(_domainTaskInstances);

您测试的方法不会将null作为第一个参数filter,而是提供Expression<...>的一些实例。

显然,您不能在Setup的表达式中省略可选参数;因此代码:

_taskInstanceRepository
    .Setup(x => x.Get(It.IsAny<Expression<Func<TaskInstance, bool>>>())) // illegal
    .Returns(_domainTaskInstances);

看起来有点像你测试的方法中的语法,允许。