如何在小部件测试期间存根不属于类的函数?
Posted
技术标签:
【中文标题】如何在小部件测试期间存根不属于类的函数?【英文标题】:How do I stub a function that does not belong to a class, during a widget test? 【发布时间】:2019-12-26 04:47:07 【问题描述】:我正在使用官方的flutter相机包(https://pub.dev/packages/camera)创建一个使用原生相机拍照的flutter应用。该应用程序会打开一个模式,该模式会根据包中的availableCameras
函数的结果加载CameraPreview
,而FloatingActionButton
在按下时会拍照。在为此模式创建小部件测试时,我不知道如何存根 availableCameras
函数以在测试期间返回我想要的内容。
我尝试使用 Mockito 测试包,但这仅支持模拟类。由于这个函数不属于一个类,我不能模拟它。
availableCameras
函数返回设备拥有的摄像头列表。我希望能够控制从这个函数返回的内容,以便我可以测试我的小部件对不同相机的反应。在小部件测试期间让此函数返回我想要的内容的正确方法是什么?
【问题讨论】:
【参考方案1】:Mockito 也可以模拟函数。在 dart 中,函数是具有call
方法的类。
因此,您可以像往常一样使用 Mockito,使用抽象的 call
方法:
class MockFunction extends Mock
int call(String param);
这个例子代表int Function(String param)
。
这意味着你可以这样做:
final int Function(String) myFn = MockFunction();
when(myFn('hello world')).thenReturn(42);
expect(myFn('hello world'), equals(42));
【讨论】:
非常有趣,但不是只有在函数被注入(例如作为参数)时才有效吗?您能否提供一个模拟***函数的示例? @HugoPassos 是的,您需要一个方法来用另一个函数替换该函数。不过,有很多不同的方法可以做到这一点。例如,该函数可以是一个可变的全局变量。 有整本书专门介绍这些模式,所以我不能在这里合理地给出明确的解决方案。 是的,但我们说的是公共图书馆。在这种情况下,我无法以任何方式替换该功能。 您不必直接使用该功能。全局var getCameras = availableCameras
应该可以解决问题。然后你的测试可以用不同的值替换它。【参考方案2】:
在这种非常特殊的情况下,您可以mock the method channel call handler。
const cameraMethodChannel = MethodChannel('plugins.flutter.io/camera');
setUpAll(()
cameraMethodChannel.setMockMethodCallHandler(cameraCallHandler);
);
tearDownAll(()
cameraMethodChannel.setMockMethodCallHandler(null);
);
Future<dynamic> cameraCallHandler(MethodCall methodCall) async
if (methodCall.method == 'availableCameras') return yourListOfCameras;
【讨论】:
以上是关于如何在小部件测试期间存根不属于类的函数?的主要内容,如果未能解决你的问题,请参考以下文章
如何在小部件测试中测试特定的 ProviderNotFoundException