C# WebApi单元测试和模拟控制器

11

我正在开发这个WebAPI项目,需要为其创建单元测试。该项目的基础是使用VS 2010创建的,然后添加了WebApi模块。

控制器的运作方式有点妨碍测试/模拟。我正在使用xUnit和Moq,但绝对没有必要坚持使用这两个。

应用程序使用特定对象来处理数据库访问,所以我有controllerObject,其构造函数需要DataAccessObject。

我在模拟controller/dataaccess pair时遇到了问题。第一个我尝试运行的测试是GetAllFromDataBase,但我真的不知道该怎么做。

编辑:

我按照Cuong Le告诉我的做法,整个流程现在都在进行中,我非常感激。但我遇到了另一个问题。要访问API,需要用户名/密码对,我的控制器使用Thread.CurrentPrincipal.Identity.Name;目前我需要设置这个值才能完全使其工作吧。

此外,valueServiceMock.Setup(service => service.GetValues()) .Returns(new[] { "value1", "value2" });

似乎并不起作用。因为代码试图访问数据库,但由于无法获得有效的用户名而得不到任何内容。


你不应该嘲笑控制器,而应该嘲笑控制器所需的服务。如果你在嘲笑控制器,那么你就无法测试控制器了。这是整个测试的重点。请看这篇文章:http://www.peterprovost.org//blog/2012/06/16/unit-testing-asp-dot-net-web-api/ - tugberk
你有检查过是否通过构造函数传递了模拟对象吗?像这样:var controller = new ValuesController(valueServiceMock.Object); - cuongle
1个回答

23
为了使您的应用程序可测试,您需要考虑设计可测试性。从技术上讲,为了实现可测试性,您的应用程序应该在层之间、组件之间甚至类之间尽可能地松散耦合。
设计可测试性的许多提示:避免使用密封的、静态的类...但是你需要注意的最流行的东西是依赖注入模式,而不是在其他对象的构造函数或方法中创建对象,这个对象应该被注入。通过这种方式,我们使类之间的依赖关系更加松散,易于通过模拟框架进行伪造。特别是对于依赖于外部资源(网络、文件或数据库)的对象。
如何通过使用依赖注入来注入对象:这就是为什么IocContainer是正确的工具,它会自动为您注入对象。我喜欢使用的IoC容器是:AutofacNInject
在这里举例说明如何将ValueService注入ValuesController:
public class ValuesController : ApiController
{
    private readonly IValueService _valueService;

    public ValuesController(IValueService valueService)
    {
        _valueService = valueService;
    }

    public string[] Get()
    {
        return _valueService.GetValues();
    }

    public string Get(int id)
    {
        return _valueService.GetValue(id);
    }
}

以下是使用Moq进行单元测试的简单代码:
var valueServiceMock = new Mock<IValueService>();
valueServiceMock.Setup(service => service.GetValues())
            .Returns(new[] { "value1", "value2" });

var controller = new ValuesController(valueServiceMock.Object);
var values = controller.Get();

Assert.AreEqual(values.Length, 2);
Assert.AreEqual(values[0], "value1");
Assert.AreEqual(values[1], "value2");

我按照你的指示做了,现在整个程序都在运行了,非常感谢。但是我又遇到了另一个问题。为了访问API,需要使用用户名/密码对,而我的控制器使用Thread.CurrentPrincipal.Identity.Name; - oSR
我本来希望能在这里解决这个问题,但我们还是另外发一个问题吧! - oSR

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接