I'm not sure if there is a way to test it directly from a StatelessWidget, but I can show you a way that makes use of some concepts of Clean Architecture. Basically, you want to decouple the UI (that is, your widgets) from pure logic. So, what I usually do is to have a class that handles the logic, like this:
class MyWidgetViewModel {
/// Whether or not the current environment is web.
/// Should only be overridden for testing purposes.
/// Otherwise, defaults to [kIsWeb].
@visibleForTesting
bool isWeb = kIsWeb;
}
Here, I have wrapped the kIsWeb constant in another variable isWeb, which defaults to kIsWeb. This means that it can be reassigned at a later time and, moreover, it is only visible to test cases thanks to the annotation @visibleForTesting.
At this point, we can reference that class in the widget. I generally use Dependency Injection with either Provider or BLoC, but here, for the sake of simplicity, I'll just pass the ViewModel in the widget constructor.
class MyWidget extends StatelessWidget {
final MyWidgetViewModel myViewModel;
const MyWidget(this.myViewModel, {Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
if (myViewModel.isWeb) { //<- Here we use `isWeb` instead of `kIsWeb`
return Text("I'm web");
} else {
return Text("I'm not web");
}
}
}
Finally, we can exploit the isWeb variable in the tests. Don't forget to pass an instance of MyWidgetViewModel() to your MyWidget during the setup of the variables.
test(
'Test based on platform (is web or not).',
() async {
// Arrange (setup)
...
final MyWidgetViewModel myViewModel = MyWidgetViewModel();
myViewModel.isWeb = true; //<- Use this to assign the value you prefer
...
// Assert (expect, verify)
...
},
);