Flutter Mockito - 模拟抛出异常

15

我刚开始在Flutter中使用Mockito:

我想在调用方法时模拟抛出异常。所以我这样做:

when(mockInstance.foo(input).thenThrow(ArgumentError);

但是当期望它抛出一个ArgumentError时:

expect(mockInstance.foo(input), throwsArgumentError);

我运行了Flutter测试,结果显示测试失败,即使它确实说明是一个ArgumentError:

 ArgumentError 
 package:mockito/src/mock.dart 346:7                             
 PostExpectation.thenThrow.<fn>
 package:mockito/src/mock.dart 123:37                            
 Mock.noSuchMethod
 package:-/--/---/Instance.dart 43:9  MockInstance.foo
 tests/Instance_test.dart 113:26 ensureArgumentErrorIsThrown

我做错了什么?

2个回答

10

如果你需要模拟异常,以下两种方法都可以:

  1. Mock the call and provide the expect function with a function that is expected to throw once it's executed (Mockito seems to fail automatically if any test throws an exception outside expect function):

    when(mockInstance.foo(input))
      .thenThrow(ArgumentError);
    
    expect(
      () => mockInstance.foo(input), // or just mockInstance.foo(input)
      throwsArgumentError,
    );
    
  2. In case it's an async call, and you are catching the exception on a try-catch block and returning something, you can use then.Answer :

    when(mockInstance.foo(input))
      .thenAnswer((_) => throw ArgumentError());
    
    final a = await mockInstance.foo(input);
    
    // assert
    verify(...);
    expect(...)
    
  3. If the exception is not thrown by a mock:

    expect(
      methodThatThrows()),
      throwsA(isA<YourCustomException>()),
    );
    

5

我遇到了同样的问题。尝试

expect(() => mockInstance.foo(input), throwsArgumentError);

这里是一个所有测试都通过的示例类。
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/mockito.dart';

void main() {
  test("",(){
    var mock = new MockA();
    when(mock.foo1()).thenThrow(new ArgumentError());

    expect(() => mock.foo1(), throwsArgumentError);
  });

  test("",(){
    var mock = new MockA();
    when(mock.foo2()).thenThrow(new ArgumentError());

    expect(() => mock.foo2(), throwsArgumentError);
  });

  test("",(){
    var mock = new MockA();
    when(mock.foo3()).thenThrow(new ArgumentError());

    expect(() => mock.foo3(), throwsArgumentError);
  });

  test("",(){
    var mock = new MockA();
    when(mock.foo4()).thenThrow(new ArgumentError());

    expect(() => mock.foo4(), throwsArgumentError);
  });
}

class MockA extends Mock implements A {}

class A {
  void foo1() {}
  int foo2() => 3;
  Future foo3() async {}
  Future<int> foo4() async => Future.value(3);
}

你能解释一下为什么我们需要在 expect(() => actual, matcher) 中传递箭头函数吗? - Sameen
很抱歉,我无法给您任何有效的解释。 - xmashallax

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接