Skip to content

Conversation

@Levi-Lesches
Copy link
Contributor

@Levi-Lesches Levi-Lesches commented Sep 19, 2025

Fixes flaky Windows unit tests on every PR, without losing too much. To actually test notifications, run the example app manually. These new tests probe the XML directly without actually passing it to the Windows SDK or even loading the DLL. To make sure we're still testing the Dart logic, I mocked out the FFI bindings, not the plugin itself, so that all the Dart validation logic still runs, but no C++ runs.

Fixes #2695

Copy link
Owner

@MaikuB MaikuB left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for looking into this. Could the issue have been addressed without having to change the main plugin the way it's been done in this PR? The issue that sticks is how the plugin required changes and makes use of a global variable to determine if the plugin should use a real implementation or a mock. Two antipatterns/code smells are happening as a result

@Levi-Lesches
Copy link
Contributor Author

Added a new constructor marked @visibleForTesting that allows passing in the mocked bindings directly

Copy link
Owner

@MaikuB MaikuB left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for making the changes. I took a pass and believe there are some improvements that could be done


/// Creates an instance of this plugin with the given (mocked) bindings.
@visibleForTesting
FlutterLocalNotificationsWindows.withBindings(
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was about to mention perhaps to rename it to FlutterLocalNotificationsWindows.private as it would be consistent with what you had on Linux. There was also an element of how the with<...> convention can lead to issues (repetition from readability perspective and could break if more arguments got introduced).

Rather than taking this approach, I noticed first-party plugins are taking an optional, nullable argument with the @visibleForTesting annotation applied to it. I think this is actually a good approach as implementation and test code would point to the same constructor. Would you be able to switch it so that the only constructor follows that pattern? An example of what I mean can be found here

}

/// Does a basic syntax check on XML.
bool _checkXml(String xml) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's file private but look this could have been private within the FlutterLocalNotificationsWindows class. Would you be able to adjust this?

Note: on a related note and not that it has to be done in this PR but I believe I missed picking this up when it comes to _globalLaunchCallback as well

import 'bindings.dart';

/// Mocked FFI bindings.
class MockBindings implements NotificationsPluginBindings {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you place this in the test folder? It's purely test related and is the approach taken when creating mocks via mocktail or mockito or hand crafted ones. Note this is also currently a stub not a mock. A mock provides the ability to record the interactions that can then be used to verify what took place. Can you also rename the class and adjust the docs accordingly to reflect this?

import 'base.dart';

/// The Windows implementation of `package:flutter_local_notifications`.
class FlutterLocalNotificationsWindows extends WindowsNotificationsBase {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With the comment I left that allows the FFI implementation to take an argument for the bindings used behind the scenes, does this perhaps render the stub redundant now? Based on my own knowledge and testing, it would be redundant but let me know if I've missed anything

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Windows unit tests are too flaky

2 participants