Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to Unit Test Delete operation using moq and xUnit?

I’m trying to Unit Test CRUD operations for an API in my WEB API project. I have a hard time figuring out how to do that for DELETE. Below is my service;

public async Task DeleteCompany(int id)
{
    var query = "DELETE FROM Companies WHERE Id = @Id";
    using(var connection = _context.CreateConnection())
    {
        await connection.ExecuteAsync(query, new {id});
    }
}

Here’s the controller

[HttpDelete("{id}")]
public async Task<IActionResult> DeleteCompany(int id)
{
    var company = await _companyRepository.GetCompanyById(id);
    if (company == null)
    {
        return NotFound();
    }
    await _companyRepository.DeleteCompany(id);
    return NoContent();
}

And below is the code for Unit Testing

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

[Theory]
[InlineData(1)]
public async Task CompanyController_DeleteCompany_ShouldReturnStatusCode204(int id)
{
    var mockCompany = new Mock<ICompanyRepository>();
    mockCompany.Setup(service => service.DeleteCompany(id))
           .Returns(Task.CompletedTask)
           .Verifiable();

    var sut = new CompanyController(mockCompany.Object);

    var result = (OkObjectResult) await sut.DeleteCompany(id);

    result.StatusCode.Should().Be(204);
}

It turned out that it returns a null value of my model (Company in this example) after debugging. That’s why the test doesn’t pass and it gets to NotFound error in the controller.

>Solution :

You need to set up the Test Double‘s GetCompanyById method so that it doesn’t return null:

[Theory]
[InlineData(1)]
public async Task CompanyController_DeleteCompany_ShouldReturnStatusCode204(int id)
{
    var mockCompany = new Mock<ICompanyRepository>();
    mockCompany.Setup(service => service.GetCompanyById(id))
        .ReturnsAsync(/*pass non-null value here*/);
    var sut = new CompanyController(mockCompany.Object);

    var result = (OkObjectResult) await sut.DeleteCompany(id);

    result.StatusCode.Should().Be(204);
    mockCompany.Verify(service => service.DeleteCompany(id);
}

On the other hand, you don’t need to set up DeleteCompany as a verifiable action since it doesn’t return anything anyway. Mocks for Commands, Stubs for Queries. Use mockCompany.Verify instead, as shown above.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading