• Updated:

Testing. Code example for c# (NUnit)

(this project contains examples on how to use NUnit. Nowadays it’s better to use XUnit for new projects).

The following are code examples to test several scenarios.

(check this project to see more testing code examples)

General tests

This is a test to check an exception is thrown for a non-async method.

The method .WithMessage("*null payload*") works as a like. Any string that contains null payload will trigger as true.

[Test]
public async Task GivenNullPayload_WhenSetupPost_ThenAssertExceptionIsThrown
{
	// given
	string url = "http://somethingsomething.com"
	string nullPayload = null;
	
	// when
	Action result = () => _service.SetUpPost(url, nullPayload);
	
	// then
	result.Should().Throw<ArgumentNullException>().WithMessage("*null payload*");
}

This is the example for an async method.

[Test]
public async Task GivenNullPayload_WhenSetupPostAsync_ThenAssertExceptionIsThrown
{
	// given
	string url = "http://somethingsomething.com";
	string nullPayload = null;
	
	// when
	Func<Task> result = () => _service.SetUpPostAsync(url, nullPayload);
	
	// then
	await result.Should().ThrowAsync<InvalidOperationException>().WithMessage("*null payload*");
}

Test a controller

  • GivenCorrectDate_WhenGetAvailability_ThenAssertCorrectReturnValue asserts a controller returns 200 when everything goes right
  • GivenWrongDate_WhenGetAvailability_ThenAssert400ReturnValue assert a controller returns 400 with specific error message
  • GivenServiceThrowsException_WhenReserveSlot_ThenAssertExceptionCaught assert method throws an exception, but it is correctly caught
public class SlotsControllerTest
{
	// class we're testing
	private SlotsController _controller;

	private Mock<ISlotsService> _slotsServiceMock;
	
	private Mock<IOptions<CoreConfig>> _iOptConfigMock;
	private Mock<CoreConfig> _configMock;
	
	[SetUp]
	public void SetUp()
	{
		_configMock = new Mock<CoreConfig>();
		_iOptConfigMock = new Mock<IOptions<CoreConfig>>();
		_iOptConfigMock.Setup(iOpt => iOpt.Value).Returns(_configMock);
		
		_slotsServiceMock = new Mock<ISlotsService>();
		_controller = new SlotsController(_slotsServiceMock.Object, _iOptConfigMock.Object);
	}


[Test]
public async Task GivenWrongDate_WhenGetAvailability_ThenAssert400ReturnValue()
{
	// given
	string date = "";
	string errorMessage = "oh no! something went wrong!";
	
	var errorMessages = new ErrorMessages
	{
		GeneralErrorMessage = errorMessage
	};
	
	_configMock.Setup(conf => conf.GeneralErrorMessage).Returns(errorMessage);
	
	// when
	var result = await _controller.GetAvailability(date) as BadRequestObjectResult;
	
	// then
	result.Should().NotBeNull();
	result.StatusCode.Should().Be(400);
	result.Value.ToString().Should().Contain(errorMessage);
}

[Test]
public async Task GivenCorrectDate_WhenGetAvailability_ThenAssertCorrectReturnValue()
{
	// given
	string date = "20241012";
	var parsedDate = new DateOnly(2024, 10, 12);
	
	string dateFormat = "yyyyMMdd";
	_configMock.Setup(conf => conf.InputDateFormat).Returns(dateFormat);
	
	var dto = new WeekAvailabilityResponse();
	_slotsServiceMock.Setup(service => service.GetWeekSlotsAsync(parsedDate)).ReturnsAsync(dto);
	
	// when
	var result = await _controller.GetAvailability(date) as OkObjectResult;
	
	// then
	result.Should().NotBeNull();
	result.StatusCode.Should().Be(200);
	result.Value.Should().Be(dto);
}

[Test]
public async Task GivenServiceThrowsException_WhenReserveSlot_ThenAssertExceptionCaught()
{
	// given
	var request = new ReserveSlotRequest();

	string errorMessage = "error when throw exception";
	var errorMessages = new ErrorMessages
	{
		GeneralErrorMessage = errorMessage
	};
	
	_configMock.Setup(conf => conf.GeneralErrorMessage).Returns(errorMessage);
	_slotsServiceMock.Setup(service => service.ReserveSlotsAsync(parsedDate)).ThrowAsync(new HttpRequestException(errorMessage));

	// when
	var result = await _controller.ReserveSlot(request) as BadRequestObjectResult
	
	// then
	result.Should().NotBeNull();
	result.StatusCode.Should().Be(400);
	result.Value.ToString().Should().Contain(errorMessage);
}