2012-08-03 67 views
8

我正在研究这个WebAPI项目,我需要为它创建单元测试。该项目的基础是使用VS 2010创建的,然后添加了WebApi模块。C#WebApi单元测试和模拟控制器

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

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

我有嘲讽控制器/数据访问对问题。我试图运行的第一个测试是GetAllFromDataBase,但我没有真正知道如何去做。

编辑:

我做了什么的Cuong乐告诉我,现在全是移动的,我真的apreciate它。但我陷入了另一个问题。要访问API,有一个用户名/密码对,我的控制器使用Thread.CurrentPrincipal.Identity.Name;现在我需要设置这个值,以使其完全工作,我猜。

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

似乎没有工作。因为代码试图访问数据库,并且什么也得不到,因为它无法获得有效的用户名以寻找

+0

你不应该嘲笑控制器,你会嘲笑控制器需要的服务。如果你嘲笑控制器,你不会测试控制器。这是完整的一点。看看这个帖子:http://www.peterprovost.org//blog/2012/06/16/unit-testing-asp-dot-net-web-api/ – tugberk 2012-08-03 22:01:55

+0

你是否检查过你通过模拟对象构造函数是这样的:var controller = new ValuesController(valueServiceMock.Object); – 2012-08-07 06:35:50

回答

18

为了让您的应用程序可测试,您需要考虑设计可测试性。从技术上讲,设计为可测试性,你的应用应该尽可能地在层之间,组件之间甚至类之间进行松耦合。

很多关于可测试性设计的提示:避免密封,静态类...但是最需要注意的是dependency injection pattern,而不是在构造器或其他对象的方法内部创建对象,这个对象应该被注射。通过这种方式,我们通过嘲笑框架使我们对产生宽松的依赖关系。特别针对依赖外部资源的对象:网络,文件或数据库。

如何使用依赖注入注入对象:这就是为什么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); 
    } 
} 

而且下面是简单的代码进行单元测试与起订量:

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"); 
+0

我做了你告诉我的事,现在整体都在移动,我真的很喜欢它。但我陷入了另一个问题。要访问API,有一个用户名/密码对,我的控制器使用Thread.CurrentPrincipal.Identity。名称; – oSR 2012-08-06 18:45:12

+0

我希望能在这里解决这个问题,但让我们再提出一个问题! – oSR 2012-08-06 18:53:54