集成测试/单元测试 - 如何决定

问题描述 投票:0回答:1

我有控制器 API 方法,我必须为其编写测试用例方法。到目前为止,我一直在为该项目编写集成测试方法。我不确定如何为 API 方法构建单元测试用例方法,如下所示:

EmployeeController.cs

[HttpPost]
public IHttpActionResult PostCancelEmployee(EmployeeRequest req)
{
    string id = req.EmployeeId;
    EmployeeDetails mgr = new EmployeeDetails(id);
    response = mgr.CancelEmployeeDetails(req);
}

如果我编写集成测试用例,那么示例输入/请求参数会根据数据库不断变化,这会导致测试用例失败。有人可以帮我使用 Moq 框架为这些类型的 API 方法编写单元测试用例吗?

unit-testing integration-testing moq
1个回答
0
投票

Microsoft 文档 有一些使用 Moq 对 API 控制器方法进行单元测试的好示例。这是重构控制器的基本示例。

员工控制器:

public class EmployeeController : ApiController
{
    IEmployeeRepository _repository;

    public EmployeeController(IEmployeeRepository repository)
    {
        _repository = repository;
    }

    [HttpGet]
    public IHttpActionResult Get(int id)
    {
        Employee employee = _repository.GetById(id);
        if (employee == null)
        {
            return NotFound();
        }
        return Ok(employee);
    }

    [HttpPost]
    public IHttpActionResult Post(Employee employee)
    {
        _repository.Add(employee);
        return CreatedAtRoute("DefaultApi", new { id = employee.Id }, employee);
    }
    
    [HttpDelete]
    public IHttpActionResult Delete(int id)
    {
        _repository.Delete(id);
        return Ok();
    }

    [HttpPut]
    public IHttpActionResult Put(Employee employee)
    {
        // Do some work (not shown).
        return Content(HttpStatusCode.Accepted, employee);
    }
}

这里最大的变化是将与数据库交互的类的使用与其创建解耦。在您的示例中,您正在 API 方法中实例化一个新的

EmployeeDetails
。最好将任何依赖项作为接口注入到控制器中,以便可以在测试中轻松模拟它。

这是一个示例单元测试,用于验证

EmployeeController
Get
方法返回类型和数据:

[TestMethod]
public void GetReturnsEmployeeWithSameId()
{
    // Arrange
    var mockRepository = new Mock<IEmployeeRepository>();
    mockRepository.Setup(x => x.GetById(42))
        .Returns(new Employee { Id = 42 });

    var controller = new EmployeeController(mockRepository.Object);

    // Act
    IHttpActionResult actionResult = controller.Get(42);
    var contentResult = actionResult as OkNegotiatedContentResult<Employee>;

    // Assert
    Assert.IsNotNull(contentResult);
    Assert.IsNotNull(contentResult.Content);
    Assert.AreEqual(42, contentResult.Content.Id);
}

链接文档中包含涵盖其余 API 方法的其他测试示例。

至于要测试什么,一般建议验证:

  • 该操作返回正确类型的响应。
  • 无效参数返回正确的错误响应。
  • 该操作调用存储库或服务层上的正确方法。
  • 如果响应包含域模型,请验证模型类型。
© www.soinside.com 2019 - 2024. All rights reserved.