【问题标题】:Checking exceptions with TestCaseData parameters使用 TestCaseData 参数检查异常
【发布时间】:2019-11-29 06:30:17
【问题描述】:

我使用 NUnit 3 TestCaseData 对象将测试数据提供给测试,并使用 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&lt;ApplicationException&gt;() 部分作为特定条件传递到TestCaseData 对象的第三个参数中以用于测试?基本上我想参数化测试的预期结果(它可能是某种类型的异常或根本没有异常)。

【问题讨论】:

    标签: nunit-3.0 fluent-assertions parameterized-tests


    【解决方案1】:

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

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

    TestCaseData 接受编译时值,而 TestCaseSource 在运行时生成它们,这是使用 ThrowNotThrow 所必需的。

    这是一种滥用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);
        }
    }
    

    【讨论】:

      【解决方案2】:

      我最终使用了这个:

      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() 方法对此有所帮助。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-04-02
        • 1970-01-01
        • 2017-01-13
        • 2018-09-08
        • 1970-01-01
        相关资源
        最近更新 更多