c# web 中的最小起订量单元测试 api
moq unit testing in c# web api
我正在尝试在 asp.net 核心 2 中测试一个网络 api 方法。
网络api
方法:
public IActionResult Delete(int id)
{
try
{
var success = sportsService.DeleteSport(id);
if (!success)
{
return new NotFoundResult();
}
return new OkResult();
}
catch (Exception e)
{
return new StatusCodeResult(400);
}
}
单元测试部分:
private Mock<ISportsService> mockService;
[SetUp]
public void Setup()
{
mockService.SetupSequence(x => x.DeleteSport(It.IsAny<int>())).
Returns(true). // OkResult();
Returns(false). // NotFoundResult()
Throws(new Exception()); //Exception
}
测试方法如下所示。我对这种方法不清楚的是,测试该方法的正确方法是什么?
[Test]
public void TestStrategyControllerWithDelete()
{
var result = controller.Delete(STRAT_ID);
var okResult = result as ObjectResult;
Assert.AreEqual(HttpStatusCode.NotFound, okResult.StatusCode);
Assert.AreEqual(HttpStatusCode.OK, okResult.StatusCode);
Assert.AreEqual(400, okResult.StatusCode);
}
我认为结果为空! 并且无法获得 okResult.StatusCode
您需要调用 controler.Delete(...) 方法 3 次以获得最小起订量 return 不同的 status/exception.
我建议对每个 returned 状态进行谨慎测试 - 每个状态(true/false)一个,例外一个。
您正在将模拟设置为:
- return
true
首次调用时
- return
false
第二次调用时
- 再次调用时抛出
new Exception()
但是,在您的测试中您只调用一次(var result = controller.Delete(STRAT_ID);
所以您的最小起订量将始终 return true
.
写 3 个单独的测试,而不是一个:
[Test]
public void Delete_ReturnsOkResult_IfDeleteSuccess()
{
const int deleteId = 1234;
mockService.Setup(x => x.DeleteSport(deleteId)).Returns(true);
var result = controller.Delete(deleteId);
Assert.IsInstanceOf<OkResult>(result);
}
单元测试应该是独立的。他们应该能够以任何顺序 运行 而不会相互干扰。但是,通过在 [SetUp]
步骤中配置 SetupSequence()
,您至少将其中的 3 个绑定在一起并强制对它们进行排序。
编辑: "and not able to get okResult.StatusCode"* 更新问题
您正在 returnOKResult, NotFoundResult and StatusCodeResult。 None 其中继承自 ObjectResult,这就是它为 NULL 的原因。我已经更新了我的代码示例以检查显式类型 (OKResult
),这将需要针对每个测试用例进行更新。
如果您想检查单个 StatusCodes,您可以将其大小写为 StatusCodeResult
,因为所有 return 类型都可以转换为这个。
你可以这样做,
1) 成功:
[Test]
public void Delete_ReturnsOkResult_IfDeleteSuccess()
{
bool isSucceed = true;
const int deleteId = 1234;
this.MockSportService(isSucceed);
var result = controller.Delete(deleteId);
var okResult = result as ObjectResult;
Assert.AreEqual(HttpStatusCode.OK, okResult.StatusCode);
}
2) 失败:
[Test]
public void Delete_ReturnsNotFound_IfIdNotFound()
{
bool isSucceed = false;
const int deleteId = 1234;
this.MockSportService(isSucceed);
var result = controller.Delete(deleteId);
// Do proper asserts
}
3) 例外,
[Test]
public void Delete_ThrowsException_IfIdNotFound()
{
bool isSucceed = false;
const int deleteId = 1234;
mockService.Setup(x => x.DeleteSport(It.IsAny<int>())).
Throws(new Exception());
// Act
var result = controller.Delete(deleteId);
// Assert
Assert.True(result is StatusCodeResult); // Asserting that the return type is StatusCodeResult
// Casting the result as StatusCodeResult object
var statusCodeResult = result as StatusCodeResult;
// Asserting the status code
Assert.AreEqual(400, statusCodeResult.StatusCode);
}
并且有成功和失败的通用模拟方法,
private void MockSportService(bool isSucceed)
{
mockService.Setup(x => x.DeleteSport(deleteId)).Returns(isSucceed);
}
我正在尝试在 asp.net 核心 2 中测试一个网络 api 方法。
网络api
方法:
public IActionResult Delete(int id)
{
try
{
var success = sportsService.DeleteSport(id);
if (!success)
{
return new NotFoundResult();
}
return new OkResult();
}
catch (Exception e)
{
return new StatusCodeResult(400);
}
}
单元测试部分:
private Mock<ISportsService> mockService;
[SetUp]
public void Setup()
{
mockService.SetupSequence(x => x.DeleteSport(It.IsAny<int>())).
Returns(true). // OkResult();
Returns(false). // NotFoundResult()
Throws(new Exception()); //Exception
}
测试方法如下所示。我对这种方法不清楚的是,测试该方法的正确方法是什么?
[Test]
public void TestStrategyControllerWithDelete()
{
var result = controller.Delete(STRAT_ID);
var okResult = result as ObjectResult;
Assert.AreEqual(HttpStatusCode.NotFound, okResult.StatusCode);
Assert.AreEqual(HttpStatusCode.OK, okResult.StatusCode);
Assert.AreEqual(400, okResult.StatusCode);
}
我认为结果为空! 并且无法获得 okResult.StatusCode
您需要调用 controler.Delete(...) 方法 3 次以获得最小起订量 return 不同的 status/exception.
我建议对每个 returned 状态进行谨慎测试 - 每个状态(true/false)一个,例外一个。
您正在将模拟设置为:
- return
true
首次调用时 - return
false
第二次调用时 - 再次调用时抛出
new Exception()
但是,在您的测试中您只调用一次(var result = controller.Delete(STRAT_ID);
所以您的最小起订量将始终 return true
.
写 3 个单独的测试,而不是一个:
[Test]
public void Delete_ReturnsOkResult_IfDeleteSuccess()
{
const int deleteId = 1234;
mockService.Setup(x => x.DeleteSport(deleteId)).Returns(true);
var result = controller.Delete(deleteId);
Assert.IsInstanceOf<OkResult>(result);
}
单元测试应该是独立的。他们应该能够以任何顺序 运行 而不会相互干扰。但是,通过在 [SetUp]
步骤中配置 SetupSequence()
,您至少将其中的 3 个绑定在一起并强制对它们进行排序。
编辑: "and not able to get okResult.StatusCode"* 更新问题
您正在 returnOKResult, NotFoundResult and StatusCodeResult。 None 其中继承自 ObjectResult,这就是它为 NULL 的原因。我已经更新了我的代码示例以检查显式类型 (OKResult
),这将需要针对每个测试用例进行更新。
如果您想检查单个 StatusCodes,您可以将其大小写为 StatusCodeResult
,因为所有 return 类型都可以转换为这个。
你可以这样做,
1) 成功:
[Test]
public void Delete_ReturnsOkResult_IfDeleteSuccess()
{
bool isSucceed = true;
const int deleteId = 1234;
this.MockSportService(isSucceed);
var result = controller.Delete(deleteId);
var okResult = result as ObjectResult;
Assert.AreEqual(HttpStatusCode.OK, okResult.StatusCode);
}
2) 失败:
[Test]
public void Delete_ReturnsNotFound_IfIdNotFound()
{
bool isSucceed = false;
const int deleteId = 1234;
this.MockSportService(isSucceed);
var result = controller.Delete(deleteId);
// Do proper asserts
}
3) 例外,
[Test]
public void Delete_ThrowsException_IfIdNotFound()
{
bool isSucceed = false;
const int deleteId = 1234;
mockService.Setup(x => x.DeleteSport(It.IsAny<int>())).
Throws(new Exception());
// Act
var result = controller.Delete(deleteId);
// Assert
Assert.True(result is StatusCodeResult); // Asserting that the return type is StatusCodeResult
// Casting the result as StatusCodeResult object
var statusCodeResult = result as StatusCodeResult;
// Asserting the status code
Assert.AreEqual(400, statusCodeResult.StatusCode);
}
并且有成功和失败的通用模拟方法,
private void MockSportService(bool isSucceed)
{
mockService.Setup(x => x.DeleteSport(deleteId)).Returns(isSucceed);
}