使用 TestCaseData 参数检查异常
Checking exceptions with TestCaseData parameters
我正在使用 NUnit 3 TestCaseData
对象将测试数据提供给测试,并使用 Fluent Assertions 库检查抛出的异常。
通常我的 TestCaseData
对象包含两个参数 param1
和 param2
用于在测试中创建某个对象的实例,然后我调用 should/should 不会抛出异常,像这样:
var subject = new Subject(param1, param2);
subject.Invoking(s => s.Add()).Should().NotThrow();
或
var subject = new Subject(param1, param2);
subject.Invoking(s => s.Add()).Should().Throw<ApplicationException>();
有没有办法将NotThrow()
和Throw<ApplicationException>()
部分作为特定条件传递到TestCaseData
对象的第三个参数中以用于测试?基本上我想参数化测试的预期结果(它可能是某种类型的异常或根本没有异常)。
[TestCaseData]
适用于 测试用例数据 ,不适用于断言方法。
我会在单独的测试中保留 NotThrow
和 Throw
以保持可读性。
如果他们共享很多设置逻辑,我会提取 that 到共享方法中以减少测试方法主体的大小。
TestCaseData
接受编译时值,而 TestCaseSource
在运行时生成它们,这是使用 Throw
和 NotThrow
.
所必需的
这是一种通过滥用 TestCaseSource
来实现的方法。
结果是一个不可读的测试方法,所以请不要在任何地方使用它。
不管怎么说:
[TestFixture]
public class ActionTests
{
private static IEnumerable<TestCaseData> ActionTestCaseData
{
get
{
yield return new TestCaseData((Action)(() => throw new Exception()), (Action<Action>)(act => act.Should().Throw<Exception>()));
yield return new TestCaseData((Action)(() => {}), (Action<Action>)(act => act.Should().NotThrow()));
}
}
[Test]
[TestCaseSource(typeof(ActionTests), nameof(ActionTestCaseData))]
public void Calculate_Success(Action act, Action<Action> assert)
{
assert(act);
}
}
我最终使用了这个:
using ExceptionResult = Action<System.Func<UserDetail>>;
[Test]
[TestCaseSource(typeof(UserEndpointTests), nameof(AddUserTestCases))]
public void User_Add(string creatorUsername, Role role, ExceptionResult result)
{
var endpoint = new UserEndpoint(creatorUsername);
var person = GeneratePerson();
var request = GenerateCreateUserRequest(person, role);
// Assertion comes here
result(endpoint.Invoking(e => e.Add(request)));
}
private static IEnumerable AddUserTestCases
{
get
{
yield return new TestCaseData(TestUserEmail, Role.User, new ExceptionResult(x => x.Should().Throw<ApplicationException>())
.SetName("{m} (Regular User => Regular User)")
.SetDescription("User with Regular User role cannot add any users.");
yield return new TestCaseData(TestAdminEmail, Role.Admin, new ExceptionResult(x => x.Should().NotThrow())
)
.SetName("{m} (Admin => Admin)")
.SetDescription("User with Admin role adds another user with Admin role.");
}
}
可读性没有大问题,此外,测试用例源代码中的 SetName()
和 SetDescription()
方法对此有帮助。
我正在使用 NUnit 3 TestCaseData
对象将测试数据提供给测试,并使用 Fluent Assertions 库检查抛出的异常。
通常我的 TestCaseData
对象包含两个参数 param1
和 param2
用于在测试中创建某个对象的实例,然后我调用 should/should 不会抛出异常,像这样:
var subject = new Subject(param1, param2);
subject.Invoking(s => s.Add()).Should().NotThrow();
或
var subject = new Subject(param1, param2);
subject.Invoking(s => s.Add()).Should().Throw<ApplicationException>();
有没有办法将NotThrow()
和Throw<ApplicationException>()
部分作为特定条件传递到TestCaseData
对象的第三个参数中以用于测试?基本上我想参数化测试的预期结果(它可能是某种类型的异常或根本没有异常)。
[TestCaseData]
适用于 测试用例数据 ,不适用于断言方法。
我会在单独的测试中保留 NotThrow
和 Throw
以保持可读性。
如果他们共享很多设置逻辑,我会提取 that 到共享方法中以减少测试方法主体的大小。
TestCaseData
接受编译时值,而 TestCaseSource
在运行时生成它们,这是使用 Throw
和 NotThrow
.
这是一种通过滥用 TestCaseSource
来实现的方法。
结果是一个不可读的测试方法,所以请不要在任何地方使用它。
不管怎么说:
[TestFixture]
public class ActionTests
{
private static IEnumerable<TestCaseData> ActionTestCaseData
{
get
{
yield return new TestCaseData((Action)(() => throw new Exception()), (Action<Action>)(act => act.Should().Throw<Exception>()));
yield return new TestCaseData((Action)(() => {}), (Action<Action>)(act => act.Should().NotThrow()));
}
}
[Test]
[TestCaseSource(typeof(ActionTests), nameof(ActionTestCaseData))]
public void Calculate_Success(Action act, Action<Action> assert)
{
assert(act);
}
}
我最终使用了这个:
using ExceptionResult = Action<System.Func<UserDetail>>;
[Test]
[TestCaseSource(typeof(UserEndpointTests), nameof(AddUserTestCases))]
public void User_Add(string creatorUsername, Role role, ExceptionResult result)
{
var endpoint = new UserEndpoint(creatorUsername);
var person = GeneratePerson();
var request = GenerateCreateUserRequest(person, role);
// Assertion comes here
result(endpoint.Invoking(e => e.Add(request)));
}
private static IEnumerable AddUserTestCases
{
get
{
yield return new TestCaseData(TestUserEmail, Role.User, new ExceptionResult(x => x.Should().Throw<ApplicationException>())
.SetName("{m} (Regular User => Regular User)")
.SetDescription("User with Regular User role cannot add any users.");
yield return new TestCaseData(TestAdminEmail, Role.Admin, new ExceptionResult(x => x.Should().NotThrow())
)
.SetName("{m} (Admin => Admin)")
.SetDescription("User with Admin role adds another user with Admin role.");
}
}
可读性没有大问题,此外,测试用例源代码中的 SetName()
和 SetDescription()
方法对此有帮助。