当前位置: 首页 > 知识库问答 >
问题:

当 Web API 操作方法返回 IHttpActionResult 时,如何对其进行单元测试?

冯鸿哲
2023-03-14

假设这是我的操作方法

public IHttpActionResult Get(int id)
{
    var status = GetSomething(id);
    if (status)
    {
        return Ok();
    }
    else
    {
        return NotFound();
    }
}

测试将是

var httpActionResult = controller.Get(1);

在这之后我如何检查我的http状态码?

共有3个答案

谭宜
2023-03-14

这是Kiran Challa的公认答案,为NUnit改编;

var valuesController = controller;
// if your action returns: NotFound()
IHttpActionResult actionResult = valuesController.Get(10);
var notFoundRes = actionResult as NotFoundResult;
Assert.IsNotNull(notFoundRes);

// if your action returns: Ok()
actionResult = valuesController.Get(11);
var posRes = actionResult as OkResult;
Assert.IsNotNull(posRes);

// if your action was returning data in the body like: Ok<string>("data: 12")
actionResult = valuesController.Get(12);
var conNegResult = actionResult as OkNegotiatedContentResult<string>;
Assert.IsNotNull(conNegResult);
Assert.AreEqual("data: 12", conNegResult.Content);

// if your action was returning data in the body like: Content<string>(HttpStatusCode.Accepted, "some updated data");
actionResult = valuesController.Get(13);
var negResult = actionResult as NegotiatedContentResult<string>;
Assert.IsNotNull(negResult);
Assert.AreEqual(HttpStatusCode.Accepted, negResult.StatusCode);
Assert.AreEqual("some updated data", negResult.Content);
龚弘业
2023-03-14

是时候重新提出一个死问题了

当前的答案都依赖于将响应对象转换为已知类型。不幸的是,在不了解控制器实现的情况下,响应似乎没有可用的层次结构或隐式转换路径。考虑以下几点:

public class MixedCodeStandardController : ApiController {

    public readonly object _data = new Object();

    public IHttpActionResult Get() {
        return Ok(_data);
    }

    public IHttpActionResult Get(int id) {
        return Content(HttpStatusCode.Success, _data);
    }
}

测试类:

var testController = new MixedCodeStandardController();

var getResult = testController.Get();
var posRes = getResult as OkNegotiatedContentResult<object>;
Assert.IsType<OkNegotiatedContentResult<object>>(getResult);
Assert.AreEqual(HttpStatusCode.Success, posRes.StatusCode);
Assert.AreEqual(testController._data, posRes.Content);

var idResult = testController.Get(1);
var oddRes = getResult as OkNegotiatedContentResult<object>; // oddRes is null
Assert.IsType<OkNegotiatedContentResult<object>>(idResult); // throws failed assertion
Assert.AreEqual(HttpStatusCode.Success, oddRes.StatusCode); // throws for null ref
Assert.AreEqual(testController._data, oddRes.Content); // throws for null ref

从黑匣子外部来看,响应流本质上是相同的。测试必须知道控制器如何实现返回调用以以这种方式对其进行测试。

相反,使用返回的IHttpActionResult中的HttpActionMessage对象。这可确保测试可以保持一致,即使控制器代码可能不是:

var testController = new MixedCodeStandardController();

var getResult = testController.Get();
var getResponse = getResult.ExecuteAsync(CancellationToken.None).Result;
Assert.IsTrue(getResponse.IsSuccessStatusCode);
Assert.AreEqual(HttpStatusCode.Success, getResponse.StatusCode);

var idResult = testController.Get(1);
var idResponse = idResult.ExecuteAsync(CancellationToken.None).Result;
Assert.IsTrue(idResponse.IsSuccessStatusCode);
Assert.AreEqual(HttpStatusCode.Success, idResponse.StatusCode);
邹桐
2023-03-14

这里Ok()只是OkResult类型的一个助手,它将响应状态设置为HttpStatusCode.Ok...所以您可以检查您的操作结果的实例是否是OkResult...一些示例(用XUnit编写):

// if your action returns: NotFound()
IHttpActionResult actionResult = valuesController.Get(10);
Assert.IsType<NotFoundResult>(actionResult);

// if your action returns: Ok()
actionResult = valuesController.Get(11);
Assert.IsType<OkResult>(actionResult);

// if your action was returning data in the body like: Ok<string>("data: 12")
actionResult = valuesController.Get(12);
OkNegotiatedContentResult<string> conNegResult = Assert.IsType<OkNegotiatedContentResult<string>>(actionResult);
Assert.Equal("data: 12", conNegResult.Content);

// if your action was returning data in the body like: Content<string>(HttpStatusCode.Accepted, "some updated data");
actionResult = valuesController.Get(13);
NegotiatedContentResult<string> negResult = Assert.IsType<NegotiatedContentResult<string>>(actionResult);
Assert.Equal(HttpStatusCode.Accepted, negResult.StatusCode);
Assert.Equal("some updated data", negResult.Content);
 类似资料:
  • 问题内容: 如果我有这样的控制器: 基本上,我从存储库中获取东西,然后将其投影到匿名类型中。 如何进行单元测试? 有一个名为的属性,但它的类型与我们预期的一样。 这是否意味着如果我想测试JSON对象是否具有我期望的属性(“ id”,“ name”,“ type”),我是否必须使用反射? 编辑: 这是我的测试: 但是我在循环中收到一个运行时错误,指出“对象不包含id的定义”。 当我将断点定义为匿名类

  • 请给出您的想法如何单元测试这样的场景?我正在使用mockito进行单元测试。我是新的mockito和单元测试,请指导。提前道谢。

  • 我陷入了单元测试场景的一个基本问题,并将感谢帮助。 我有一个类,它调用在DB中将标志设置为true。 我的测试: 我被要求测试并检查是否正在使用相关数据调用。 由于返回类型无效,我如何测试它?

  • 我正在尝试测试我的方法,它在Java中返回一个double。

  • 我正在尝试使用状态代码201的Ihttpstatus标头获取此JSON响应,并将IHttpActionResult作为我的方法返回类型。 我想要返回的JSON: {“客户 ID”: 324} 我的方法: JSON返回: “ID”:324,“日期”:“2014-06-18T17:35:07.8095813-07:00”, 以下是我尝试过的一些返回,它们要么给了我uri null错误,要么给了我类似于

  • 问题内容: 如何在单元测试中测试 hashCode()函数? 问题答案: 每当我覆盖equals和hash代码时,我都会按照Joshua Bloch在“ Effective Java”第3章中的建议编写单元测试。我确保equals和hash代码是自反的,对称的和可传递的。我还确保“不等于”对所有数据成员均正常工作。 当我检查对equals的调用时,我还要确保hashCode的行为符合预期。像这样: