控制器集成测试应该断言什么
作者:互联网
在Web api端点上进行集成测试时,我应该重点关注什么?
我的端点也正在调用域服务.
我应该嘲笑该服务吗?使用当前代码是不可能的,因为我将需要实例化控制器以传递模拟服务.
我对服务返回值感兴趣吗?其实并不是.
我只对端点是否成功触发感兴趣,但是我应该隔离我猜的服务调用.
任何建议,欢迎:-)
测试
[TestClass]
public class SchoolyearControllerTests
{
private TestServer _server;
[TestInitialize]
public void FixtureInit()
{
_server = TestServer.Create<Startup>();
}
[TestCleanup]
public void FixtureDispose()
{
_server.Dispose();
}
[TestMethod]
public void Get()
{
var response = _server.HttpClient.GetAsync(_server.BaseAddress + "/api/schoolyears").Result;
var result = response.Content.ReadAsAsync<IEnumerable<SchoolyearDTO>>().GetAwaiter().GetResult();
Assert.AreEqual(response.StatusCode, HttpStatusCode.OK);
}
}
测试动作
[HttpGet]
public async Task<IHttpActionResult> Get()
{
var schoolyears = await service.GetSchoolyears();
return Ok(schoolyears);
}
解决方法:
在Web服务上进行集成测试的麻烦在于,它不能告诉您太多有关该问题的信息,或者即使实际上存在一个问题,也不能告诉您问题的根源.它将成功或失败.因此,在这方面,您得到了200响应码还是500响应码…但是它失败了,因为:
>服务器无法访问
> Web服务未启动,或尝试启动时失败
>防火墙阻止了网络
>找不到数据库记录
>存在数据库架构问题,实体框架未启动
正确地.
它实际上可以是任何东西-开发机器上的结果可能与生产机器上的结果不同-那么它对您的应用程序有什么真正的启示?
打造强大软件的原因在于,测试您的产品是否能够正确,优雅且稳健地处理任何一种情况.
我这样写控制器动作:
public HttpResponseMessage Get(int id)
{
try
{
var person = _personRepository.GetById(id);
var dto = Mapper.Map<PersonDto>(person);
HttpResponseMessage response = Request.CreateResponse<PersonDto>(HttpStatusCode.OK, dto);
return response;
}
catch (TextFileDataSourceException ex)
{
HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.InternalServerError);
return response;
}
catch (DataResourceNotFoundException ex)
{
HttpResponseMessage response = Request.CreateErrorResponse(HttpStatusCode.NotFound, ex);
return response;
}
catch (FormatException ex)
{
HttpResponseMessage response = Request.CreateErrorResponse(HttpStatusCode.InternalServerError, ex);
return response;
}
catch (Exception ex)
{
HttpResponseMessage response = Request.CreateErrorResponse(HttpStatusCode.InternalServerError, ex);
return response;
}
}
一个try块获取数据,进行dto并以200码返回数据.这里处理了几种错误情况,但没有一种情况表明我的Web服务本身存在问题,有些(404错误)甚至没有表明该应用程序存在问题-如果我的应用程序找不到一个IFPECT,我会收到NotFoundException和404错误记录-如果发生这种情况,我的应用程序在这种情况下会起作用.
因此,如果发生这些错误情况中的任何一个,则不是因为Web服务存在问题,而不一定是应用程序存在问题.但是我可以测试我的Web服务是否针对任何这些预期条件返回了正确的响应.
此控制器操作的测试如下所示:
[Test]
public void CanGetPerson()
{
#region Arrange
var person = new Person
{
Id = 1,
FamilyName = "Rooney",
GivenName = "Wayne",
MiddleNames = "Mark",
DateOfBirth = new DateTime(1985, 10, 24),
DateOfDeath = null,
PlaceOfBirth = "Liverpool",
Height = 1.76m,
TwitterId = "@WayneRooney"
};
Mapper.CreateMap<Person, PersonDto>();
var mockPersonRepository = new Mock<IPersonRepository>();
mockPersonRepository.Setup(x => x.GetById(1)).Returns(person);
var controller = new PersonController(mockPersonRepository.Object);
controller.Request = new HttpRequestMessage(HttpMethod.Get, "1");
controller.Configuration = new HttpConfiguration(new HttpRouteCollection());
#endregion
#region act
HttpResponseMessage result = controller.Get(1);
#endregion
#region assert
Assert.AreEqual(HttpStatusCode.OK, result.StatusCode);
#endregion
}
[Test]
public void CanHandlePersonNotExists()
{
#region Arrange
var mockPersonRepository = new Mock<IPersonRepository>();
mockPersonRepository.Setup(x => x.GetById(1)).Throws<DataResourceNotFoundException>();
var controller = new PersonController(mockPersonRepository.Object)
{
Request = new HttpRequestMessage(HttpMethod.Get, "1"),
Configuration = new HttpConfiguration(new HttpRouteCollection())
};
#endregion
#region Act
HttpResponseMessage result = controller.Get(1);
#endregion
#region Assert
Assert.AreEqual(HttpStatusCode.NotFound, result.StatusCode);
#endregion
}
[Test]
public void CanHandleServerError()
{
#region Arrange
var mockPersonRepository = new Mock<IPersonRepository>();
mockPersonRepository.Setup(x => x.GetById(1)).Throws<Exception>();
var controller = new PersonController(mockPersonRepository.Object);
controller.Request = new HttpRequestMessage(HttpMethod.Get, "1");
controller.Configuration = new HttpConfiguration(new HttpRouteCollection());
#endregion
#region Act
HttpResponseMessage result = controller.Get(1);
#endregion
#region Assert
Assert.AreEqual(HttpStatusCode.InternalServerError, result.StatusCode);
#endregion
}
请注意,我正在介绍一个模拟存储库,并让我的模拟存储库触发404和服务器错误的预期异常,并确保Web服务正确处理它.
这说明我的Web服务应按预期方式处理特殊情况并返回适当的代码:200/404/500.
尽管有些是错误状态,有些是成功状态,但这些结果都没有一个表明我的Web服务存在问题-它的行为与预期的完全一样,这就是我要测试的内容.
Web服务上的“跨网络”集成测试不会告诉您应用程序的健壮性或正确性,甚至无法返回正确的数据或响应代码.
不要尝试重新测试WebAPI … Microsoft已经为其编写了大量测试-数百个测试夹具类,数千种测试方法:
假定WebAPI可以正常工作,并且不需要您再次对其进行测试.专注于测试您的应用程序代码,并确保Web服务能够正常处理成功和错误情况.
如果要检查您的Web服务已连接并且在网络上可用,请打开浏览器并对其进行手动测试;否则,请执行以下步骤.无需自动执行此操作;结果会因环境和外部条件而异.
以相同的方式测试应用程序的每一层,模拟出上一层,并测试当前层是否处理了上层的所有可能结果.
服务的客户端应用程序应该做同样的事情:模拟该Web服务,并假装它提供了404-并检查它是否应按要求进行处理.
标签:asp-net-web-api,asp-net-web-api2,integration-testing,c 来源: https://codeday.me/bug/20191028/1950688.html