Using Button::triggerClick in a unit test

I’m trying to create a unit test, and I called a button’s triggerClick(), and it works as expected if I add MessageManager::getInstance()->runDispatchLoopUntil (1000); after it.

How can I make the test “click” without running the dispatch loop for a while? Is there a way to call the dispatch loop until all it’s queued messages were dispatched? Or a different better way to do this?

So far I came up with this for my tests:

void messageManagerFinishTasks()
    MessageManager::callAsync (MessageManager::deleteInstance);
    while (MessageManager* manager = MessageManager::getInstanceWithoutCreating())
        manager->runDispatchLoopUntil (0);
    MessageManager::getInstance(); // Create a new MessageManager instance

Seems to work but I’d love to hear if there are better ways to do it.

Cleaner(?) version using C++11 lambdas:

void messageManagerFinishTasks()
    bool tasksPending = true;
    MessageManager::callAsync ([&tasksPending]() { tasksPending = false; });
    while (tasksPending)
        MessageManager::getInstance()->runDispatchLoopUntil (0);

I’d really discourage you from running the modal loop like that - it could get recursive if something else tries to quit while it’s waiting to quit.

Also, whenever you’re using callAsync you need to be really careful about lifetime of the lambda you give it - in this case giving it a stack local variable is incredibly dangerous because it could be delivered later after the function has returned, in which case it’d corrupt a random memory address in the stack.

Definitely follow the example of the way the projucer’s shutdown code does this - it’s a lot safer!

In this case it messageManagerFinishTasks won’t return until the given lambda has been executed, so tasksPending's stack frame is still valid when it’s used. I guess a comment to explain that would indeed help :slight_smile:

As for the original question - would you use triggerClick in a unit test, is it actually what it’s for? Is this a good way to do it?

I guess you could use it for unit testing, but its main purpose is to make the button visually go down and up so that the user can see that it’s been triggered.

1 Like