How to mock FlutterBluePlus
for testing.
Since version 1.10.0, FlutterBluePlus.instance
has been deprecated in favor of static functions.
Therefore, to mock FlutterBluePlus you must:
- Wrap
FlutterBluePlus
in a mockable non-static class - Add your mocked functions to the mockable class.
- Use the mockable class in your code
A full example is here.
Create the following class:
import '../flutter_blue_plus.dart';
/// Wrapper for FlutterBluePlus in order to easily mock it
/// Wraps all static calls for testing purposes
class FlutterBluePlusMockable {
Future<void> startScan({
List<Guid> withServices = const [],
Duration? timeout,
Duration? removeIfGone,
bool oneByOne = false,
bool androidUsesFineLocation = false,
}) {
return FlutterBluePlus.startScan(
withServices: withServices,
timeout: timeout,
removeIfGone: removeIfGone,
oneByOne: oneByOne,
androidUsesFineLocation: androidUsesFineLocation);
}
Stream<BluetoothAdapterState> get adapterState {
return FlutterBluePlus.adapterState;
}
Stream<List<ScanResult>> get scanResults {
return FlutterBluePlus.scanResults;
}
bool get isScanningNow {
return FlutterBluePlus.isScanningNow;
}
Stream<bool> get isScanning {
return FlutterBluePlus.isScanning;
}
Future<void> stopScan() {
return FlutterBluePlus.stopScan();
}
void setLogLevel(LogLevel level, {color = true}) {
return FlutterBluePlus.setLogLevel(level, color: color);
}
LogLevel get logLevel {
return FlutterBluePlus.logLevel;
}
Future<bool> get isSupported {
return FlutterBluePlus.isSupported;
}
Future<String> get adapterName {
return FlutterBluePlus.adapterName;
}
Future<void> turnOn({int timeout = 60}) {
return FlutterBluePlus.turnOn(timeout: timeout);
}
List<BluetoothDevice> get connectedDevices {
return FlutterBluePlus.connectedDevices;
}
Future<List<BluetoothDevice>> get systemDevices {
return FlutterBluePlus.systemDevices;
}
Future<PhySupport> getPhySupport() {
return FlutterBluePlus.getPhySupport();
}
Future<List<BluetoothDevice>> get bondedDevices {
return FlutterBluePlus.bondedDevices;
}
}
Using e.g. Mockito, create a mock for the FlutterBluePlusMockable
class, and build your tests and stubs.
Use the mockable class where needed, e.g. in main.dart
:
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
MyApp({Key? key}) : super(key: key);
//instance of FlutterBluePlus that will be passed
//throughout the app as necessary
FlutterBluePlusMockable bluePlusMockable = FlutterBluePlusMockable();//<--
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'My app',
theme: ThemeData(
primarySwatch: Colors.lightGreen,
),
home: FindDevicesScreen(
bluePlusMockable: bluePlusMockable,
);
);
}
}
Within your code, replace all calls to FlutterBluePlus
with the mockable instance, e.g.:
FlutterBluePlus.isScanning
--> bluePlusMockable.isScanning
FlutterBluePlus.startScan
--> bluePlusMockable.startScan
FlutterBluePlus.scanResults
--> bluePlusMockable.scanResults
etc.
Detailed example is here.