How to recreate a JUCEApplication for testing?

Hi all,

I’m trying to write some tests for a juce::JUCEApplication derived class.

I can happily create an instance of the app like so:

JUCE_CREATE_APPLICATION_DEFINE (mvp::Application)


std::unique_ptr<juce::JUCEApplicationBase> createApplicationInstance()
{
    return std::unique_ptr<juce::JUCEApplicationBase> {juce::JUCEApplicationBase::createInstance()};
}

// Test space
{
    juce::JUCEApplicationBase::CreateInstance = &juce_CreateApplication;
    juce::ScopedJuceinitialiser_GUI libraryInitialiser;

    {
        const auto app = createAppliationInstance();

        REQUIRE (app != nullptr);
        REQUIRE (app->initialiseApp());
        REQUIRE (app->shutdownApp() != 0);
    }
}

However, in the next test when I want to initialise a fresh instance of the app, like so:

const auto app = createApplicationInstance();
app->initialiseApp();

I hit an assertion in juce_Singleton.h, line 72 because the JuceMainMenuBarHolder is set to not be recreated after deletion.

Is there any workaround for this that will let me create new instances on the app during my tests? In a real world scenario it would of course make sense to not create multiple instances, but for tests it’s extremely useful.

To answer my own question - it seems the solution to this is to not do it!

I’d gone down a bit of a rabbit hole trying to replicate the START_JUCE_APPLICATION macro which isn’t really necessary. The solution I’ve landed on is to instead have a default constructible proxy for the application that can easily be used in tests. Then the ‘real’ app, derived from JUCEApplication simply forwards calls to the proxy.

Maybe there is still a way to do it the way I’d originally tried, but I don’t think it’s worth it.

2 Likes

A solution could be to spawn a new process for each test?
But it probably doesn’t worth the cost neither.

1 Like

Performing integration tests at this level will be kind of difficult. Most automation tools like Robot Framework would require you to restart the process if you need to test a different clean scenario.