Creating a MouseEvent?

I have a JUCE Component that needs to trigger another callback in another part of my code whenever it receives certain UI callbacks such as mouseDown.

I always write unit tests for the re-usable bits of my code. So in this case, in the unit test I would manually call the component’s mouseDown and then check that the desired side effect occurred.

However I just can’t figure out how to do that! calling mouseDown requires me to pass in a MouseEvent, which I cannot instantiate without giving it a MouseInputSource. And that MouseInputSource is, as far as I can see, completely impossible to instantiate, obtain an instance of it from anywhere, inherit from, or anything else I can think of!

JUCE fiercely resists all my attempts to write a mocking framework for it to make its UI bits unit testable in any way…

In the meantime, does anyone has an idea how to unit test things like that?

4 Likes

Maybe : just don’t try testing GUIs? :wink:

But if you really have to do it, generate mouse moves and clicks using OS specific APIs?

In this specific use case, it would be a lot more time-consuming and error-prone to manually test all the things that can happen in the actual running app… it would be much better to unit-test things in isolation. If it were possible. (At least if you write code the way I do…)

OS-specific APIs are not an option either – this is cross-platform code.

2 Likes

Something like this would be great!

Any chance your Unit Tests can use Desktop::getMainMouseSource()? that would give you a MouseInputSource.

Yep, I also just discovered that I can make my unit test framework (I use Catch2) have a juce::Desktop instance and this allows me to do a few more things in there.

I’ll explore this direction and report back here :slight_smile:

1 Like

Might be even better to use something like Desktop::setMousePosition()?

Nope, because afaics juce::Desktop doesn’t actually let you click anything with the mock mouse.

Also, iiuc, this call would actually move the real mouse cursor. Unit tests shouldn’t do things like that!

Yes it would.

@timur Did you ever figure out how to do this?

Yep, this works:

// at the top of your tests: 
juce::ScopedJuceInitialiser_GUI juceRuntime; 

// in a test:
auto mms = juce::Desktop::getInstance().getMainMouseSource();
auto fakeEvent = juce::MouseEvent (mms, /* other ctor arguments here */);
component.mouseDown (fakeEvent);