Rob*_*ads 5 unit-testing dart flutter
我想知道是否有一种方法可以覆盖库函数,这样它们就不会触发或只返回其他内容。
import 'package:foo_package/exposing_foo_function.dart';
class TestableClass {
bool bar() {
return foo(); //foo is from the imported library
}
}
Run Code Online (Sandbox Code Playgroud)
测试:
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);
});
}
Run Code Online (Sandbox Code Playgroud)
诸如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();
}
}
Run Code Online (Sandbox Code Playgroud)
然后测试:
void main() {
test('TestableClass.bar() when foo_package.foo() returns false', () {
bool fakeFoo() => false;
TestableClass testableClass = TestableClass(foo: fakeFoo);
expect(testableClass.bar(), isFalse);
});
}
Run Code Online (Sandbox Code Playgroud)
类似的方法是将全局/静态函数包装为类的实例方法:
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();
}
}
Run Code Online (Sandbox Code Playgroud)
然后您的测试可以FooManager像任何其他类一样进行模拟并设置fooManager为模拟版本。(或者,如果您更喜欢全局变量的依赖反转,请将您的模拟版本传递FooManager为TestableClass构造参数。)
当然,以上所有内容仅对您自己通过包装器的调用有帮助。如果您无法控制的代码调用这些函数,那将无济于事。在这种情况下,您最好的做法可能是向函数的作者抱怨缺乏可测试性。