I've just started Unit Testing and I'm having some trouble understanding how should I write them.
I have this code
[Theory]
[InlineData("00000000-0000-0000-0000-000000000001")]
[InlineData("00000000-0000-0000-0000-000000000002")]
public void Delete_Intern(Guid id)
{
_internService.Setup(x => x.Delete(It.IsAny<Guid>())).Returns(true);
var actual = (OkResult) _internsController.DeleteIntern(id);
Assert.True(actual is OkResult);
}
[Theory]
[InlineData("00000000-0000-0000-0000-000000000000")]
[InlineData("00000000-0000-0000-0000-000000000005")]
public void Delete_Intern_ShouldFail(Guid id)
{
_internService.Setup(x => x.Delete(It.IsAny<Guid>())).Returns(false);
var actual = (OkResult)_internsController.DeleteIntern(id);
Assert.False(actual is OkResult);
}
which tests this method:
[HttpDelete("{id}")]
public IActionResult DeleteIntern(Guid id)
{
bool deleted = _internService.Delete(id);
if (deleted == false)
{
return NotFound("Intern cannot be found");
}
return Ok();
}
how should I write the ShouldFail method so it will be able to do that cast?
Right now, I'm getting an exception, saying that I cannot cast an object of type NotFoundResult to an OkResult.
I tried casting it to ObjectResult, then checking if it is an OkResult. But it doesn't work, because OkResult cannot be cast to ObjectResult.
Thanks.
CodePudding user response:
The NotFound()
method will return NotFoundResult
, if you want to test it just cast asNotFoundResult
instead of OKResult
.
Because NotFoundResult
isn't equal to OKResult
[Theory]
[InlineData("00000000-0000-0000-0000-000000000000")]
[InlineData("00000000-0000-0000-0000-000000000005")]
public void Delete_Intern_ShouldFail(Guid id)
{
_internService.Setup(x => x.Delete(It.IsAny<Guid>())).Returns(false);
var actual = (NotFoundResult)_internsController.DeleteIntern(id);
Assert.True(actual is NotFoundResult);
}
Or you can use StatusCodeResult
type from _internsController.DeleteIntern
because both of NotFoundResult
and OKResult
are inherit that.
[Theory]
[InlineData("00000000-0000-0000-0000-000000000000")]
[InlineData("00000000-0000-0000-0000-000000000005")]
public void Delete_Intern_ShouldFail(Guid id)
{
_internService.Setup(x => x.Delete(It.IsAny<Guid>())).Returns(false);
StatusCodeResult actual = _internsController.DeleteIntern(id);
Assert.False(actual is OKResult);
}
CodePudding user response:
I personally like this use the Assert.IsAssignableFrom<T>
because you can directly assert that you get the proper response back. It also casts the result which allows you to easily assert the contents of it afterwards.
Example for your OKResult
:
[Theory]
[InlineData("00000000-0000-0000-0000-000000000001")]
[InlineData("00000000-0000-0000-0000-000000000002")]
public void Delete_Intern_ShouldFail(Guid id)
{
_internService.Setup(x => x.Delete(It.IsAny<Guid>())).Returns(false);
var result = _internsController.DeleteIntern(id);
var notFound = Assert.IsAssignableFrom<NotFoundObjectResult>(result);
var response = Assert.IsAssignableFrom<string>(notFound.Value);
Assert.Equal("Intern cannot be found", response);
}
I added a check on the string
in the response as well just to illustrate how easy it would be to add such checks.