了解单元测试的工作原理

时间:2015-12-10 11:05:08

标签: asp.net .net entity-framework unit-testing moq

我从未编写单元测试,但我想在我的新项目中使用它们。以下是我的代码示例:

public class UnitOfWork : IDisposable, IUnitOfWork
{
    private IDbContext context = new MyDbContext();

    private IUserRepository userRepository;

    public IUserRepository UserRepository 
    {
        get
        {
            if (this.userRepository== null)
            {
                this.userRepository = new UserRepository (context);
            }
            return userRepository;
        }
    }
}

public class UserController : Controller
{
    private IUnitOfWork unitOfWork;

    public UserController(IUnitOfWork unitOfWork)
    {
        this.unitOfWork = unitOfWork;
    }

    public ActionResult GetSomeUsers () 
    {
        var users = unitOfWork.UserRepository.GetSomeUsers(/*Some condition*/);
        return View(users);
    }
}

让我们假设var users = unitOfWork.UserRepository.GetSomeUsers(/*Some condition*/);里面有一些复杂的查询。 我想知道的第一件事是如何对该查询进行单元测试,是否必须创建一个单独的数据库,该数据库具有预定义的记录和针对该数据库的查询? 第二件事是如何使用模拟的UserRepository来测试控制器方法?

如果你能写一个简短的例子或者给我一些教程链接,那就太好了。

1 个答案:

答案 0 :(得分:0)

  • 我是否必须创建一个单独的数据库,该数据库具有针对该数据库的预定义记录和查询?

如果您希望实现集成测试,那么是创建一个包含测试数据的数据库并对其进行查询。集成测试非常重要且有用。另一方面,如果您希望创建单元测试,那么您需要以某种方式模拟数据库访问,因为单元测试不与环境交互,但它只测试功能本身。

参见例如this answer获取有关单元测试和集成测试之间差异的更多信息。

  • 如何仅使用模拟的UserRepository测试控制器方法?

假设方法GetSomeUsers返回字符串列表,单元测试可能如下所示。 HTH

[TestMethod]
public void GetSomeUsers_WhenCalled_RetunsView()
{
    // Arrange
    Mock<IUnitOfWork> unitOfWorkMock = new Mock<IUnitOfWork>();
    Mock<IUserRepository> userRepositoryMock = new Mock<IUserRepository>();

    List<string> listOfFakeUsers = new List<string> { "John Doe", "etc." };
    userRepositoryMock.Setup(ur => ur.GetSomeUsers()).Returns(listOfFakeUsers);

    unitOfWorkMock.SetupGet(uow => uow.UserRepository).Returns(
                                                          () => userRepositoryMock.Object);
    UserController controller = new UserController(unitOfWorkMock.Object); 

    // Act
    ActionResult result = controller.GetSomeUsers();

    // Assert
    Assert.IsInstanceOfType(result, typeof(ViewResult));
}