如何在Asp.net MVC中编写集成和系统测试

Rob*_*nik 9 asp.net-mvc integration-testing system-testing

我的应用程序

我的应用程序设计如下所示:

  • Web应用程序层 - 具有使用POCO和调用服务的控制器和视图的asp.net MVC应用程序
  • 服务层 - 使用POCO和调用存储库的业务流程
  • 数据层 - 使用POCO并以EF模型的形式与模型通信的存储库,该模型是同一层的一部分
  • POCO层 - 定义用于这些层之间的相互通信的所有类

因此,我的数据层对数据模型实现完全透明,因为上层根本不使用数据实体.

测试

据我所知,单元,集成和系统测试(与Asp.net MVC有关)是这样的:

  • 单元测试 - 这个很容易.模拟解耦对象并将其注入单元测试中,因此经过测试的单元将使用它们
  • 集成测试 - 应该制作一组生产功能单元并模拟其余部分:编写集成测试,测试控制器,服务和存储库集成,而不实际使用生产数据库
  • 系统测试 - 在所有层上运行测试而不进行任何模拟,这意味着我也必须使用生产(测试)数据库

问题

我可以很容易地看到如何编写单元测试以及系统测试,但我不知道如何编写集成测试?也许我对这些的看法完全被扭曲了,我根本不理解它们.

如何为Asp.net MVC应用程序编写集成和系统测试?
或者任何.net应用程序?

一些有助于解释问题的代码

假设我有以下课程:

  • TaskController 打电话给 TaskService
  • TaskService 打电话给 TaskRepository
  • TaskRepository 在内部操纵EF数据

所以这是我的(缩写)类:

public class TaskController
{
    private ITaskService service;

    // injection constructor
    public TaskController(ITaskService service)
    {
        this.service = service;
    }

    // default constructor
    public TaskController() : this(new TaskService()) {}

    public ActionResult GetTasks()
    {
        return View(this.service.GetTasks());
    }
    ...
}

public class TaskService : ITaskService
{
    private ITaskRepository repository;

    // injection constructor
    public TaskService(ITaskRepository repository)
    {
        this.repository = repository;
    }

    // default constructor
    public TaskService() : this(new TaskRepository()) {}

    public IList<Task> GetTasks()
    {
        return this.repository.GetTasks();
    }
    ...
}

public class TaskRepository : ITaskRepository
{
    public IList<Task> GetTasks()
    {
        // code that gets tasks from EF and converts to Task POCOs
    }
    ...
}
Run Code Online (Sandbox Code Playgroud)

单元测试很简单,看起来像这样:

public void UnitTest()
{
    var mock = new Mock<ITaskService>();
    // other code that mocks the service

    TaskController controller = new TaskController(mock.Object);

    // do the test
}
Run Code Online (Sandbox Code Playgroud)

但是当涉及到集成测试时,我如何仅模拟集成的某些部分.

public void IntegrationTest()
{
    // no mocking at all
    TaskController = new TaskController();
    // do some testing
}
Run Code Online (Sandbox Code Playgroud)

首先,我不能在这里模拟数据库?我可以模拟存储库,但有真正的服务和控制器...

Bri*_*ins 5

集成测试应该测试组件之间的集成.虽然单元测试测试单个组件的各个部分,但集成测试组件之间的交互,并且旨在实时工作.因此,集成测试将利用数据库和任何其他外部依赖项,最好在单元测试中模拟这些服务.

对我来说,系统测试将是功能测试(使用类似的东西进行另一级测试),或者通过testcomplete或telerik的QA工具等工具进行ui测试.

HTH.