用于 dart/flutter 测试的覆盖/模拟库函数 [英] Override/mock library functions for dart/flutter testing

查看:31
本文介绍了用于 dart/flutter 测试的覆盖/模拟库函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道是否有一种方法可以覆盖库函数,这样它们就不会触发或只返回其他内容.

I was wondering if there is a way to override library functions so they don't fire or just return something else.

import 'package:foo_package/exposing_foo_function.dart';

class TestableClass {
  bool bar() {
    return foo(); //foo is from the imported library
  }
}

测试:

void main() {

  test('TestableClass.bar() when foo_package.foo() returns false', () {
    TestableClass testableClass = TestableClass();

    // Something to make foo_package.foo() return false.

    expect(testableClass.bar(), isFalse);

  });
}

推荐答案

Things like mockito 通过创建实现模拟类接口的模拟类来工作.但是,这不适用于全局和静态函数.

Things like mockito work by creating mock classes that implement the interface of the mocked class. That doesn't work for global and static functions, however.

您可以做的是避免直接调用这些全局/静态函数,而是通过额外的间接级别调用它们.例如:

What you instead can do is to avoid calling those global/static functions directly and instead call them through an extra level of indirection. For example:

import 'package:foo_package/exposing_foo_function.dart' as foo_package;

class TestableClass {
  final bool Function() foo;

  TestableClass({this.foo = foo_package.foo});

  bool bar() {
    return foo();
  }
}

然后进行测试:

void main() {
  test('TestableClass.bar() when foo_package.foo() returns false', () {
    bool fakeFoo() => false;
    TestableClass testableClass = TestableClass(foo: fakeFoo);
    expect(testableClass.bar(), isFalse);
  });
}

类似的方法是将全局/静态函数包装为类的实例方法:

A similar approach is to wrap the global/static functions as instance methods of a class:

import 'package:foo_package/exposing_foo_function.dart' as foo_package;

class FooManager {
  bool foo() => foo_package.foo();
}

var fooManager = FooManager();

class TestableClass {
  bool bar() {
    return fooManager.foo();
  }
}

然后你的测试可以像任何其他类一样模拟 FooManager 并将 fooManager 设置为模拟版本.(或者,如果您更喜欢全局变量的依赖倒置,请将 FooManager 的模拟版本作为构造参数传递给 TestableClass.)

and then your tests can mock FooManager like any other class and set fooManager to the mocked version. (Or if you prefer dependency inversion to global variables, passing your mocked version of FooManager to TestableClass as a construction argument.)

当然,以上所有内容仅对您自己通过包装器的调用有帮助.如果您无法控制的代码调用这些函数,那将无济于事.在这种情况下,您最好的做法可能是向函数的作者抱怨缺乏可测试性.

Of course, all of the above will help only for your own calls that go through your wrappers. It won't help if code you don't control calls those functions. In that case, your best course of action might be to complain to the function's author about lack of testability.

这篇关于用于 dart/flutter 测试的覆盖/模拟库函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆