1

我正在使用 NUnit 3TestCaseData对象将测试数据提供给测试,并使用 Fluent Assertions 库来检查抛出的异常。

通常我的TestCaseData对象包含两个参数param1param2用于在测试中创建某个对象的实例,然后我调用应该/不应该抛出异常的方法,如下所示:

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?基本上我想参数化测试的预期结果(它可能是某种类型的异常或根本没有异常)。

4

2 回答 2

1

[TestCaseData]用于测试用例数据,而不是断言方法。

我会将NotThrowand保留Throw在单独的测试中以保持可读性。如果它们共享很多设置逻辑,我会将其提取共享方法中以减少测试方法主体的大小。

TestCaseData接受编译时值,而TestCaseSource在运行时生成它们,这对于使用Throwand是必要的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);
    }
}
于 2019-07-24T15:30:47.227 回答
0

我最终使用了这个:

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()

于 2019-07-24T15:54:06.953 回答