I'm a big fan of TestCases because they make it trivial to test more edge cases, and the anti-testers seem happier with fewer lines of testing code. I've always struggled with exception testing though.
In my code I have a validation function that checks if there is 1 and only 1 instance in the config. If there are 0 I throw a KeyNotFoundException, and if there's more than 1 a AmbiguousMatchException.
private void ThrowIfNotInConfig(string endpointRef)
{
var count = _config.Endpoints?.Count(x => x.Ref.Equals(endpointRef)) ?? 0;
if (count == 0)
{
throw new KeyNotFoundException($"{nameof(ThrowIfNotInConfig)} - " +
$"No Endpoint in appSettings with the ref {endpointRef}");
}
if (count > 1)
{
throw new AmbiguousMatchException($"{nameof(ThrowIfNotInConfig)} - " +
$"More than 1 Endpoint in appSettings with the ref {endpointRef}");
}
}
Is there a way I can avoid splitting these into 2 separate tests, just because of the exception type, that's neater than this? I don't like doing a try catch in a test, and I feel there should be a way to test against the Exception, like ExpectedException used to.
[TestCase(0, ExpectedResult = "KeyNotFoundException")]
[TestCase(2, ExpectedResult = "AmbiguousMatchException")]
public string ThrowIfNotInConfig_GIVEN_NotASingleEndpointInConfig_THEN_ThrowError(int configOccurrences)
{
// Arrange
const string endpointRef = "ABC";
var config = _validConfig;
config.Endpoints.RemoveAll(x => x.Ref == endpointRef);
config.Endpoints
.AddRange(Enumerable.Range(0, configOccurrences)
.Select(x => new MiraklEndpointConfig { Ref = endpointRef })
);
_config.Setup(c => c.Value).Returns(config);
var service = new URLThrottlingService(_mockLogger.Object, _config.Object);
try
{
// Act
service.IsOKToCallEndpoint(endpointRef);
}
catch (Exception exception)
{
return exception.GetType().Name;
}
return "";
}