如何在Visual Studio中编写Web API的测试代码?
How to write test code for Web API in Visual Studio?
我对测试项目有点陌生。我目前有一个 Web api 项目,其中包含 Get、Put、Post 和 Delete 方法。在编写测试用例时,我很困惑。我是否应该编写测试代码来测试 Http URL?
我的网站api代码:
// GET api/values/5
[HttpGet("{id}")]
public IActionResult Get(string id)
{
using (var unitOfWork = new UnitOfWork(_db))
{
var r = unitOfWork.Resources.Get(id);
unitOfWork.Complete();
Models.resource result = ConvertResourceFromCoreToApi(r);
if (result == null)
{
return NotFound();
}
else
{
return Ok(result);
}
}
}
在我的测试项目中,我有点卡在这里。我们正在使用 Xunit。如何编写测试代码来测试Get方法?或者我应该编写代码来测试 URL api/values/5,但是如何呢?
[Fact]
public void GetTest()
{
using (var unitOfWork = new UnitOfWork(new MockDatabase()))
{
}
}
如有任何帮助,我们将不胜感激。
您需要对控制器进行一些设计更改以使其易于测试。在您的操作中,您正在创建一个实例,这将使使用对控制器的虚假依赖项进行测试变得困难。此外,您的控制器应该依赖于抽象而不是具体化,这将使控制器更易于测试。
public class MyWebApiController : ApiController {
private IUnitOfWork unitOfWork;
public MyWebApiController(IUnitOfWork unitOfWork) {
this.unitOfWork = unitOfWork;
}
// GET api/values/5
[HttpGet("{id}")]
public IActionResult Get(string id) {
var r = unitOfWork.Resources.Get(id);
unitOfWork.Complete();
Models.resource result = ConvertResourceFromCoreToApi(r);
if (result == null) {
return NotFound();
} else {
return Ok(result);
}
}
//...other code
}
注意控制器使用依赖注入来注入 IUnitOfWork
。这使控制器更易于测试,因为您可以在单元测试时注入其依赖项的模拟。
从那里只是创建控制器的实例并使用依赖项的模拟调用被测方法。
[Fact]
public void GetTest() {
//Arrange (Setup the parts needed to run test)
var unitOfWork = new MockUnitOfWork(new MockDatabase());
//Or using your mocking framework of choice
//var unitOfWork = Mock.Of<IUnitOfWork>(); //this is using Moq
var controller = new MyWebApiController(unitOfWork);
var id = "Test Id value here";
//Act (call the method under test)
var result - controller.Get(id);
//Assert (check results)
//...Do your assertion pertaining to result of calling method under test
}
在真正对控制器进行单元测试之前,您需要进行一些更改。您需要将 UnitOfWork class 的实例传递到控制器的构造函数中。然后你的控制器方法代码变成:
// GET api/values/5
[HttpGet("{id}")]
public IActionResult Get(string id)
{
var r = unitOfWork.Resources.Get(id);
unitOfWork.Complete();
Models.resource result = ConvertResourceFromCoreToApi(r);
if (result == null)
{
return NotFound();
}
else
{
return Ok(result);
}
然后在你的单元测试中你这样做:
[Fact]
public void GetTest()
{
// Arrange
// You really want to mock your unit of work so you can determine
// what you are going to send back
var unitOfWork = new MockUnitOfWork();
var systemUnderTest = new Controller(unitOfWork);
system.Request = new HttpRequestMessage();
// Act
var result = systemUnderTest.Get(1);
// Assert
// Here you need to verify that you got back the expected result
}
将 UnitOfWork class 注入控制器可能是另一个问题。 Mark Seemann 在这个问题上有出色的 post,但可能有点高级。有许多不同的方法可以用更简单的方法(但可能不是那么健壮的方法)来实现这一点。 Google 是你的朋友。但是如果你有问题,post另一个问题。
希望对您有所帮助。
我对测试项目有点陌生。我目前有一个 Web api 项目,其中包含 Get、Put、Post 和 Delete 方法。在编写测试用例时,我很困惑。我是否应该编写测试代码来测试 Http URL?
我的网站api代码:
// GET api/values/5
[HttpGet("{id}")]
public IActionResult Get(string id)
{
using (var unitOfWork = new UnitOfWork(_db))
{
var r = unitOfWork.Resources.Get(id);
unitOfWork.Complete();
Models.resource result = ConvertResourceFromCoreToApi(r);
if (result == null)
{
return NotFound();
}
else
{
return Ok(result);
}
}
}
在我的测试项目中,我有点卡在这里。我们正在使用 Xunit。如何编写测试代码来测试Get方法?或者我应该编写代码来测试 URL api/values/5,但是如何呢?
[Fact]
public void GetTest()
{
using (var unitOfWork = new UnitOfWork(new MockDatabase()))
{
}
}
如有任何帮助,我们将不胜感激。
您需要对控制器进行一些设计更改以使其易于测试。在您的操作中,您正在创建一个实例,这将使使用对控制器的虚假依赖项进行测试变得困难。此外,您的控制器应该依赖于抽象而不是具体化,这将使控制器更易于测试。
public class MyWebApiController : ApiController {
private IUnitOfWork unitOfWork;
public MyWebApiController(IUnitOfWork unitOfWork) {
this.unitOfWork = unitOfWork;
}
// GET api/values/5
[HttpGet("{id}")]
public IActionResult Get(string id) {
var r = unitOfWork.Resources.Get(id);
unitOfWork.Complete();
Models.resource result = ConvertResourceFromCoreToApi(r);
if (result == null) {
return NotFound();
} else {
return Ok(result);
}
}
//...other code
}
注意控制器使用依赖注入来注入 IUnitOfWork
。这使控制器更易于测试,因为您可以在单元测试时注入其依赖项的模拟。
从那里只是创建控制器的实例并使用依赖项的模拟调用被测方法。
[Fact]
public void GetTest() {
//Arrange (Setup the parts needed to run test)
var unitOfWork = new MockUnitOfWork(new MockDatabase());
//Or using your mocking framework of choice
//var unitOfWork = Mock.Of<IUnitOfWork>(); //this is using Moq
var controller = new MyWebApiController(unitOfWork);
var id = "Test Id value here";
//Act (call the method under test)
var result - controller.Get(id);
//Assert (check results)
//...Do your assertion pertaining to result of calling method under test
}
在真正对控制器进行单元测试之前,您需要进行一些更改。您需要将 UnitOfWork class 的实例传递到控制器的构造函数中。然后你的控制器方法代码变成:
// GET api/values/5
[HttpGet("{id}")]
public IActionResult Get(string id)
{
var r = unitOfWork.Resources.Get(id);
unitOfWork.Complete();
Models.resource result = ConvertResourceFromCoreToApi(r);
if (result == null)
{
return NotFound();
}
else
{
return Ok(result);
}
然后在你的单元测试中你这样做:
[Fact]
public void GetTest()
{
// Arrange
// You really want to mock your unit of work so you can determine
// what you are going to send back
var unitOfWork = new MockUnitOfWork();
var systemUnderTest = new Controller(unitOfWork);
system.Request = new HttpRequestMessage();
// Act
var result = systemUnderTest.Get(1);
// Assert
// Here you need to verify that you got back the expected result
}
将 UnitOfWork class 注入控制器可能是另一个问题。 Mark Seemann 在这个问题上有出色的 post,但可能有点高级。有许多不同的方法可以用更简单的方法(但可能不是那么健壮的方法)来实现这一点。 Google 是你的朋友。但是如果你有问题,post另一个问题。
希望对您有所帮助。