其他分享
首页 > 其他分享> > 控制器集成测试应该断言什么

控制器集成测试应该断言什么

作者:互联网

在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已经为其编写了大量测试-数百个测试夹具类,数千种测试方法:

https://aspnetwebstack.codeplex.com/SourceControl/latest#test/System.Web.Http.Test/Controllers/ApiControllerTest.cs

假定WebAPI可以正常工作,并且不需要您再次对其进行测试.专注于测试您的应用程序代码,并确保Web服务能够正常处理成功和错误情况.

如果要检查您的Web服务已连接并且在网络上可用,请打开浏览器并对其进行手动测试;否则,请执行以下步骤.无需自动执行此操作;结果会因环境和外部条件而异.

以相同的方式测试应用程序的每一层,模拟出上一层,并测试当前层是否处理了上层的所有可能结果.

服务的客户端应用程序应该做同样的事情:模拟该Web服务,并假装它提供了404-并检查它是否应按要求进行处理.

标签:asp-net-web-api,asp-net-web-api2,integration-testing,c
来源: https://codeday.me/bug/20191028/1950688.html