使用相同的参数链接多个调用以返回不同的结果



我正在编写一个具有广泛单元测试覆盖率的Flutter应用程序。
我正在使用Mockito来模拟我的课程。
来自一个JavaAndroid)的世界,我可以使用Mockito来链接调用以在后续调用中返回不同的值。
我希望这能奏效。

import 'package:test/test.dart';
import 'package:mockito/mockito.dart';
void main() {
  test("some string test", () {
    StringProvider strProvider = MockStringProvider();
    when(strProvider.randomStr()).thenReturn("hello");
    when(strProvider.randomStr()).thenReturn("world");
    expect(strProvider.randomStr(), "hello");
    expect(strProvider.randomStr(), "world");
  });
}
class StringProvider {
  String randomStr() => "real implementation";
}
class MockStringProvider extends Mock implements StringProvider {}

但是,它会抛出:

Expected: 'hello'
Actual:   'world'
  Which: is different.

我发现唯一有效的方法是跟踪自己。

void main() {
  test("some string test", () {
    StringProvider strProvider = MockStringProvider();
    var invocations = 0;
    when(strProvider.randomStr()).thenAnswer((_) {
      var a = '';
      if (invocations == 0) {
        a = 'hello';
      } else {
        a = 'world';
      }
      invocations++;
      return a;
    });
    expect(strProvider.randomStr(), "hello");
    expect(strProvider.randomStr(), "world");
  });
}
00:

01 +1:所有测试均通过!

有没有更好的方法?

使用列表并返回带有removeAt的答案:

import 'package:test/test.dart';
import 'package:mockito/mockito.dart';
void main() {
  test("some string test", () {
    StringProvider strProvider = MockStringProvider();
    var answers = ["hello", "world"];
    when(strProvider.randomStr()).thenAnswer((_) => answers.removeAt(0));
    expect(strProvider.randomStr(), "hello");
    expect(strProvider.randomStr(), "world");
  });
}
class StringProvider {
  String randomStr() => "real implementation";
}
class MockStringProvider extends Mock implements StringProvider {}

在测试开始时,您不会被迫调用when

StringProvider strProvider = MockStringProvider();
when(strProvider.randomStr()).thenReturn("hello");
expect(strProvider.randomStr(), "hello");
when(strProvider.randomStr()).thenReturn("world");
expect(strProvider.randomStr(), "world");

Mockito是飞镖有不同的行为。后续调用将覆盖该值。

选项 1 - 带存根

我不确定 mockito,但您可以使用参数匹配器来做到这一点,并创建一个覆盖该方法而不是使用 mock 的存根类,例如:

class StrProviderStub implements StrProvider {
    StrProviderStub(this.values);
    List<String> values;
    int _currentCall = 0;
    @override
    String randomStr() {
        final value = values[_currentCall];
        _currentCall++;
        return value;
    }
}

然后在测试中使用该存根而不是模拟

选项 2 - 使用带闭包的扩展(首选)

extension MultipleExpectations<T> on PostExpectation<T> {
  void thenAnwserInOrder(List<T> bodies) {
    final safeBody = Queue.of(bodies);
    thenAnswer((realInvocation) => safeBody.removeFirst());
  }
}
# Then... use it like:
when(mock).thenAnwserInOrder(['First call', 'second call']);

我打开了这个问题,看看是否可以将其添加到框架本身 https://github.com/dart-lang/mockito/issues/568

相关内容

  • 没有找到相关文章

最新更新