我该如何编写这些单元测试?

时间:2017-10-02 16:11:04

标签: c# unit-testing moq

我正在尝试编写单元测试,但我无法弄清楚如何委派函数。

应用程序是一个MVC应用程序,单元测试依赖于moc数据(它们不使用数据库)。

我们对其中一项服务进行了更改,现在该单元测试测试该服务是否失败。我需要对单元测试进行的调整似乎不起作用,这就是我需要帮助的地方。

首先,这是改变之前的工作方式:

要测试的服务中的功能:

public Project GetProject(int projectId)
{    
    return _context.Projects.Find(projectId);    
}

在我们的单元测试中替换委托函数:

protected override void Given()
{
    GetMockFor<IRiskAliveContext>()    
    .Setup(ctx => ctx.Projects.Find(1))    
    .Returns(GetTestProject(1));
}

基本上,我们说只要服务调用context.Projects.Find(1),就从GetTestProject(1)返回模拟项目。

在我们做出改变之前,这个工作正常:

public Project GetProject(int projectId)
{
    return _context.Projects.Include("Report").FirstOrDefault(p => p.ProjectId == projectId);    
}

我们似乎无法将委托函数替换为context.Projects.Include("report").FirstOrDefault(...)的调用,至少与context.Project.Find(...)的调用方式不同。当我尝试按如下方式替换函数时,我得到NotSupportedException

protected override void Given()
{    
    GetMockFor<IRiskAliveContext>()    
    .Setup(ctx => ctx.Projects.Include("Report").FirstOrDefault(p => p.ProjectId == 1))
    .Returns(GetTestProject(1));
}

在调用时,有没有不同的方法替换委托函数...包括(...)。FirstOrDefault(...)?

1 个答案:

答案 0 :(得分:0)

对于这种方法,我喜欢模拟集合(在这种情况下为ctx.Projects),然后向该集合添加各种数据以检查是否应用了正确的过滤器。例如,在您的情况下,我将添加具有不同ProjectId的其他项目,并确认只返回正确的项目,因为这种测试将提供更多的价值,您应该能够模拟这个更容易。

我不会详细介绍如何模仿DbSetInclude,因为这些问题已在其他问题中得到解答。这些问题应该是一个很好的起点:

How to add an item to a Mock DbSet (using Moq)

Moqing Enity Framework 6 .Include() using DbSet<>