【问题标题】:Override/mock library functions for dart/flutter testing用于 dart/flutter 测试的覆盖/模拟库函数
【发布时间】:2021-11-01 14:57:54
【问题描述】:

我想知道是否有办法覆盖库函数,这样它们就不会触发或只返回其他内容。

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);

  });
}

【问题讨论】:

    标签: flutter unit-testing dart


    【解决方案1】:

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

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

    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);
      });
    }
    

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

    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。)

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

    【讨论】:

    • 这正是我一直在做的,效果很好。我想知道是否有另一种方法。
    猜你喜欢
    • 2018-11-15
    • 1970-01-01
    • 2021-08-22
    • 2020-01-02
    • 2023-04-04
    • 2021-01-07
    • 2021-06-12
    • 1970-01-01
    • 2022-11-22
    相关资源
    最近更新 更多