Visual studio 如何在VisualStudio中编写Web API的测试代码?
我对测试项目有点陌生。我目前有一个web api项目,其中包含Get、Put、Post和Delete方法。说到编写测试用例,我很困惑。我应该编写测试代码来测试Http URL吗 我的web api代码:Visual studio 如何在VisualStudio中编写Web API的测试代码?,visual-studio,asp.net-web-api,automated-tests,xunit,testcase,Visual Studio,Asp.net Web Api,Automated Tests,Xunit,Testcase,我对测试项目有点陌生。我目前有一个web api项目,其中包含Get、Put、Post和Delete方法。说到编写测试用例,我很困惑。我应该编写测试代码来测试Http URL吗 我的web api代码: // GET api/values/5 [HttpGet("{id}")] public IActionResult Get(string id) { using (var unitOfWork = new UnitOfWork(_db))
// 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
}
[事实]
公共无效GetTest(){
//安排(设置运行测试所需的部件)
var unitOfWork=new MockUnitOfWork(new MockDatabase());
//或者使用你选择的模拟框架
//var unitOfWork=Mock.Of();//这是使用Moq
var控制器=新的MyWebApicController(unitOfWork);
var id=“此处的测试id值”;
//Act(调用测试中的方法)
var结果-controller.Get(id);
//断言(检查结果)
//…执行与调用测试中方法的结果相关的断言
}
参考资料:您需要对控制器进行一些设计更改,以便于测试。在您的操作中,您正在创建一个实例,这将使测试与控制器的假依赖关系变得困难。此外,您的控制器应该依赖于抽象而不是具体化,这将使控制器更易于测试
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
}
[事实]
公共无效GetTest(){
//安排(设置运行测试所需的部件)
var unitOfWork=new MockUnitOfWork(new MockDatabase());
//或者使用你选择的模拟框架
//var unitOfWork=Mock.Of();//这是使用Moq
var控制器=新的MyWebApicController(unitOfWork);
var id=“此处的测试id值”;
//Act(调用测试中的方法)
var结果-controller.Get(id);
//断言(检查结果)
//…执行与调用测试中方法的结果相关的断言
}
参考资料:在对控制器进行真正的单元测试之前,您需要做一些更改。您需要将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);
}
然后在单元测试中执行以下操作:
[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类注入控制器可能是另一个问题。马克·西曼在这个问题上有很好的见解,但可能有点超前。有许多不同的方法可以通过更简单的方法(但可能不是健壮的方法)实现这一点。谷歌是你的朋友。但是如果你有问题的话,再发一个问题
希望这能有所帮助。在真正对控制器进行单元测试之前,您需要做一些更改。您需要将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);
}
然后在单元测试中执行以下操作:
[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类注入控制器可能是另一个问题。马克·西曼在这个问题上有很好的见解,但可能有点超前。有许多不同的方法可以通过更简单的方法(但可能不是健壮的方法)实现这一点。谷歌是你的朋友。但是如果你有问题的话,再发一个问题
希望有帮助。视情况而定。你在写单元测试还是集成测试?我相信是单元测试。你应该知道的。您可以在这里阅读更多关于单元与集成的内容:对于本例,您可以调用这些方法来对api进行单元测试。是的,我们正在编写单元测试。抱歉,这可能是一个愚蠢的问题,但如何从单元测试中调用控制器中的方法?在“using(var unitOfWork=new unitOfWork(new MockDatabase())”中,我应该使用var r=xxxController.Get(“some id”)之类的东西来调用该方法吗?MichaelDotKnox对您的回答非常好。随你的便,视情况而定。你在写单元测试还是集成测试?我相信是单元测试。你应该知道的。您可以在这里阅读更多关于单元与集成的内容:对于本例,您可以调用这些方法来对api进行单元测试。是的,我们正在编写单元测试。抱歉,这可能是一个愚蠢的问题,但如何从单元测试中调用控制器中的方法?在“using(var unitOfWork=new unitOfWork(new MockDatabase())”中,我应该使用var r=xxxController.Get(“some id”)之类的东西来调用该方法吗?MichaelDotKnox对您的回答非常好。去吧,谢谢你!那真的很有帮助!非常感谢。那真的很有帮助!谢谢你的回复。这对于开始学习WebAPI的单元测试是一个很好的参考!很乐意帮忙。如果答案有用,你可以投票表决。快乐编码!!!谢谢你的回复。这对于开始学习WebAPI的单元测试是一个很好的参考!很乐意帮忙。如果答案有用,你可以投票表决。快乐编码!!!