TestCases 如何测试抛出不同的异常?
How can TestCases test different exceptions are thrown?
我是 TestCases 的忠实粉丝,因为它们使测试更多边缘案例变得微不足道,而且反测试者似乎更愿意使用更少的测试代码行。不过,我一直在为异常测试而苦苦挣扎。
在我的代码中,我有一个验证函数,用于检查配置中是否有 1 个且只有 1 个实例。如果有 0 个,我抛出一个 KeyNotFoundException,如果有超过 1 个,我抛出一个 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}");
}
}
有没有一种方法可以避免将它们分成 2 个单独的测试,只是因为异常类型,这比这更整洁?我不喜欢在测试中做 try catch,我觉得应该有一种方法来测试异常,就像 ExpectedException 过去那样。
[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 "";
}
感谢canton7 and ,我现在有了这个,这就是我想要的
[TestCase(0, typeof(KeyNotFoundException))]
[TestCase(2, typeof(AmbiguousMatchException))]
public void ThrowIfNotInConfig_GIVEN_NotASingleEndpointInConfig_THEN_ThrowError(int configOccurrences, Type exception)
{
// 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);
// Act / Assert
Assert.Throws(exception, () => service.IsOKToCallEndpoint(endpointRef));
}
我是 TestCases 的忠实粉丝,因为它们使测试更多边缘案例变得微不足道,而且反测试者似乎更愿意使用更少的测试代码行。不过,我一直在为异常测试而苦苦挣扎。
在我的代码中,我有一个验证函数,用于检查配置中是否有 1 个且只有 1 个实例。如果有 0 个,我抛出一个 KeyNotFoundException,如果有超过 1 个,我抛出一个 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}");
}
}
有没有一种方法可以避免将它们分成 2 个单独的测试,只是因为异常类型,这比这更整洁?我不喜欢在测试中做 try catch,我觉得应该有一种方法来测试异常,就像 ExpectedException 过去那样。
[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 "";
}
感谢canton7 and
[TestCase(0, typeof(KeyNotFoundException))]
[TestCase(2, typeof(AmbiguousMatchException))]
public void ThrowIfNotInConfig_GIVEN_NotASingleEndpointInConfig_THEN_ThrowError(int configOccurrences, Type exception)
{
// 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);
// Act / Assert
Assert.Throws(exception, () => service.IsOKToCallEndpoint(endpointRef));
}