How do you unittest exceptions in Dart?

后端 未结 6 684
没有蜡笔的小新
没有蜡笔的小新 2020-12-09 00:58

Consider a function that does some exception handling based on the arguments passed:

List range(start, stop) {
    i         


        
相关标签:
6条回答
  • 2020-12-09 01:33

    I like this approach:

    test('when start > stop', () {
      try {
        range(5, 3);
      } on ArgumentError catch(e) {
        expect(e.message, 'start must be less than stop');
        return;
      }
      throw new ExpectException("Expected ArgumentError");  
    });
    
    0 讨论(0)
  • 2020-12-09 01:40

    An exception is checked using throwsA with TypeMatcher.

    Note: isInstanceOf is now deprecated.

    List range(start, stop) {
        if (start >= stop) {
          throw new ArgumentError("start must be less than stop");
        }
        // remainder of function
    }
    
    
    test("check argument error", () {
      expect(() => range(1, 2), throwsA(TypeMatcher<ArgumentError>()));
    }); 
    
    0 讨论(0)
  • 2020-12-09 01:40

    I used the following approach:

    First you need to pass in your method as a lambda into the expect function:

    expect(() => method(...), ...)
    

    Secondly you need to use throwsA in combination with isInstanceOf.

    throwsA makes sure that an exception is thrown, and with isInstanceOf you can check if the correct Exception was thrown.

    Example for my unit test:

    expect(() => parser.parse(raw), throwsA(isInstanceOf<FailedCRCCheck>()));
    

    Hope this helps.

    0 讨论(0)
  • 2020-12-09 01:41

    For simple exception testing, I prefer to use the static method API:

    Expect.throws(
      // test condition
      (){ 
        throw new Exception('code I expect to throw');
      },
      // exception object inspection
      (err) => err is Exception
    );
    
    0 讨论(0)
  • 2020-12-09 01:47

    In this case, there are various ways to test the exception. To simply test that an unspecific exception is raised:

    expect(() => range(5, 5), throwsException);
    

    to test that the right type of exception is raised:

    there are several predefined matchers for general purposes like throwsArgumentError, throwsRangeError, throwsUnsupportedError, etc.. for types for which no predefined matcher exists, you can use TypeMatcher<T>.

    expect(() => range(5, 2), throwsA(TypeMatcher<IndexError>()));
    

    to ensure that no exception is raised:

    expect(() => range(5, 10), returnsNormally);
    

    to test the exception type and exception message:

    expect(() => range(5, 3), 
        throwsA(predicate((e) => e is ArgumentError && e.message == 'start must be less than stop')));
    

    here is another way to do this:

    expect(() => range(5, 3), 
      throwsA(allOf(isArgumentError, predicate((e) => e.message == 'start must be less than stop'))));
    

    (Thanks to Graham Wheeler at Google for the last 2 solutions).

    0 讨论(0)
  • 2020-12-09 01:49

    As a more elegant solution to @Shailen Tuli's proposal, if you want to expect an error with a specific message, you can use having.

    In this situation, you are looking for something like this:

    expect(
      () => range(5, 3),
      throwsA(
        isA<ArgumentError>().having(
          (error) => error.message,        // The feature you want to check.
          'message',                       // The description of the feature.
          'start must be less than stop',  // The error message.
        ),
      ),
    );
    
    0 讨论(0)
提交回复
热议问题