9

我的应用程序

我有一个看起来像这样的应用程序设计:

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

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

测试

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

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

问题

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

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

Some code that helps explain the problem

Suppose I have classes like:

  • TaskController calls into TaskService
  • TaskService calls into TaskRepository
  • TaskRepository manipulate EF data internally

So here are my (abbreviated) classes:

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
    }
    ...
}

Unit test is simple and would look like this:

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

    TaskController controller = new TaskController(mock.Object);

    // do the test
}

But when it comes to an integration test, how do I mock only certain parts of the integration.

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

First of all I can't just mock database here? I could mock repository and have real service and controller though...

4

3 回答 3

5

Integration tests should test the integration between components. While unit tests test individual pieces of a single component, integration tests the interactions between components, and are meant to work live. So an integration test would utilize a database and any other external dependencies, where its best to mock these services in unit testing.

System test to me would be functional testing (another level of testing using something like fit), or ui testing through a tool like testcomplete or telerik's QA tool.

HTH.

于 2010-09-30T12:41:02.773 回答
2

Integration tests that don't involve the UI can still be written in NUnit, xUnit, etc.

For ASP.NET MVC in particular (or any web application), you can use WatiN or Selenium to write system/integration tests using the UI.

You might also want to look at T.S.T. for T-SQL unit testing, and SpecFlow if you are curious about BDD in .NET.

Note: I wrote this before the question was updated with code and a description of the specific situation. It doesn't really address the question anymore, but hopefully will still be interesting/useful to someone.

于 2010-09-30T13:09:02.767 回答
2

I just replied to a related question: Integration tests implementation. I think it addressed the issue here, by presenting a clear approach to take.

Part of the issue is that higher level integration tests get too complex v. quickly. Its the nature of the problem, so I prefer to make sure all the separate pieces work as intended, through unit tests and focused integration tests depending on the class involved.

With the above in place, you only need to make sure the separate pieces are hooked correctly, so I use the full system tests for that. This has the best of its effect if the code follows SOLID and DRY.

于 2010-09-30T18:19:48.087 回答