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

时间:2010-09-30 12:09:17

标签: 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
    }
    ...
}

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

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

    TaskController controller = new TaskController(mock.Object);

    // do the test
}

但是当谈到集成测试时,我如何只模拟集成的某些部分。

public void IntegrationTest()
{
    // no mocking at all
    TaskController = new TaskController();
    // do some testing
}

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

3 个答案:

答案 0 :(得分:5)

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

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

HTH。

答案 1 :(得分:2)

不涉及UI的集成测试仍然可以用NUnit,xUnit等编写。

对于ASP.NET MVC(或任何Web应用程序),您可以使用WatiNSelenium使用UI编写系统/集成测试。

您可能还想查看T.S.T.进行T-SQL单元测试,如果您对.NET中的BDD感到好奇,可以查看SpecFlow

注意:我在使用代码和特定情况的描述更新问题之前写了这个。它不再真正解决这个问题,但希望对某人来说仍然有趣/有用。

答案 2 :(得分:2)

我刚刚回复了一个相关的问题:Integration tests implementation。我认为它通过提出明确的方法来解决这个问题。

部分问题是更高级别的集成测试变得过于复杂。它是问题的本质,所以我更愿意通过单元测试和集中测试集成测试来确保所有单独的部分按预期工作,具体取决于所涉及的类。

有了上述内容,您只需要确保单独的部分正确挂钩,因此我使用完整的系统测试。如果代码遵循SOLID和DRY,则效果最好。