# Unit Test with catch C++

**URL:** <https://forum.juce.com/t/unit-test-with-catch-c/26827>\
**Category:** General JUCE discussion\
**Created:** [March 15, 2018, 6:27pm UTC](https://forum.juce.com/t/unit-test-with-catch-c/26827 "2018-03-15T18:27:06Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![jcaceres](https://avatars.discourse-cdn.com/v4/letter/j/b5a626/32.png) [@jcaceres](https://forum.juce.com/u/jcaceres)\
**Post date:** [March 15, 2018, 6:27pm UTC](https://forum.juce.com/t/unit-test-with-catch-c/26827/1 "2018-03-15T18:27:06Z")

</div>

Hi,

I am trying to run some unit tests using Catch. I need to have the JUCE event loop running for these tests to work.

I am able to use `juce::UnitTest`. To do this, I create a  
`class JuceLexTests: public JUCEApplicationBase`  
then call a `UnitTestRunner` inside its `void initialise` method, and use the  
`START_JUCE_APPLICATION(JuceLexTests)` macro.

However, I am not able to replicate this approach with catch.

Is it possible to run the JUCE event loop from unit tests in Catch?

Thanks.

---

<div class="post-metadata">

**Author:** ![mcmartin](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/mcmartin/32/7432_2.png) [@mcmartin](https://forum.juce.com/u/mcmartin)\
**Post date:** [March 15, 2018, 10:47pm UTC](https://forum.juce.com/t/unit-test-with-catch-c/26827/2 "2018-03-15T22:47:10Z")

</div>

Did you try calling `Catch::Session().run()` inside the `initialise` method?

---

<div class="post-metadata">

**Author:** ![jcaceres](https://avatars.discourse-cdn.com/v4/letter/j/b5a626/32.png) [@jcaceres](https://forum.juce.com/u/jcaceres)\
**Post date:** [March 15, 2018, 11:56pm UTC](https://forum.juce.com/t/unit-test-with-catch-c/26827/3 "2018-03-15T23:56:07Z")

</div>

> [@McMartin](#):
>
> Catch::Session().run()

That did the trick. Thanks!

---

<div class="post-metadata">

**Author:** ![jcaceres](https://avatars.discourse-cdn.com/v4/letter/j/b5a626/32.png) [@jcaceres](https://forum.juce.com/u/jcaceres)\
**Post date:** [May 30, 2018, 7:58pm UTC](https://forum.juce.com/t/unit-test-with-catch-c/26827/4 "2018-05-30T19:58:41Z")

</div>

Hi. After working on all tests that don’t need the event loop running, I am coming back to this. The approach above works to run these tests. However, the problem is that `Catch::Session().run()` doesn’t return until all tests are completed. This means that, if I call `Catch::Session().run()` inside the `initialise` method, this method doesn’t return until all tests are completed. The event loop only starts after `initialise` returns. Any idea on how to make this work? Thanks!

---

<div class="post-metadata">

**Author:** ![jcaceres](https://avatars.discourse-cdn.com/v4/letter/j/b5a626/32.png) [@jcaceres](https://forum.juce.com/u/jcaceres)\
**Post date:** [May 31, 2018, 12:19am UTC](https://forum.juce.com/t/unit-test-with-catch-c/26827/5 "2018-05-31T00:19:36Z")

</div>

I also have the same issue when I use UnitTestRunner. Any hints one how to run unit tests that require the main event loop would be appreciated.

---

<div class="post-metadata">

**Author:** ![JeffersonBledsoe](https://avatars.discourse-cdn.com/v4/letter/j/bb73d2/32.png) [@JeffersonBledsoe](https://forum.juce.com/u/JeffersonBledsoe)\
**Post date:** [May 31, 2018, 6:38am UTC](https://forum.juce.com/t/unit-test-with-catch-c/26827/6 "2018-05-31T06:38:30Z")

</div>

Would using the AsyncUpdater class solve the issue, calling `Catch::Session.run()` from within handleAsyncCallback? This would make sure the message loop was first running before running the unit tests

---

<div class="post-metadata">

**Author:** ![jcaceres](https://avatars.discourse-cdn.com/v4/letter/j/b5a626/32.png) [@jcaceres](https://forum.juce.com/u/jcaceres)\
**Post date:** [May 31, 2018, 8:34pm UTC](https://forum.juce.com/t/unit-test-with-catch-c/26827/7 "2018-05-31T20:34:53Z")

</div>

Hi, thanks for the suggestion! I tried this, and although `inizialise` returns, the loop event thread doesn’t actually do anything until Catch is done. This means that any test that need the event loop using catch don’t work. I am not sure if this is a Catch or a JUCE issue.

Specify, this is what I have:

```auto
class AsyncCath : public AsyncUpdater {
public:
    virtual void handleAsyncUpdate() override {
        Catch::Session().run();
    }
};

```

And in the `initialise` methods in the JUCEApplication:

```auto
void initialise(const String &commandLineParameters) override {
        m_Catch->triggerAsyncUpdate();
        /// I added some code here that needs the event loop here to make sure this works.
        /// it only gets triggered once Catch returns, but this method (initialise) returns immediately,
        /// so I am not sure what's going on.
    }

```

So maybe there’s a need create `AsyncCath` on a different thread?

---

<div class="post-metadata">

**Author:** ![vallant](https://avatars.discourse-cdn.com/v4/letter/v/c57346/32.png) [@vallant](https://forum.juce.com/u/vallant)\
**Post date:** [August 11, 2020, 11:24am UTC](https://forum.juce.com/t/unit-test-with-catch-c/26827/8 "2020-08-11T11:24:28Z")

</div>

I know that this is a rather old thread, but maybe this still helps.  
I’ve faced exactly the same issue and found a rather simple solution. Use this class:

```
#pragma once
#include <juce_core/juce_core.h>
#include <juce_events/juce_events.h>

class ScopedMessageThread : juce::Thread
{
public:
	ScopedMessageThread() : juce::Thread("message thread")
	{
		startThread();
		auto wasSignaled = semaphore.wait ();
		juce::ignoreUnused (wasSignaled);
	}

	~ScopedMessageThread()
	{
		juce::MessageManager::getInstance()->stopDispatchLoop();
	    stopThread (10);
	}

private:
    void run () override
    {
        initializer.reset(new juce::ScopedJuceInitialiser_GUI);
		semaphore.signal();
		juce::MessageManager::getInstance()->runDispatchLoop();
    }

	juce::WaitableEvent semaphore;
	std::unique_ptr<juce::ScopedJuceInitialiser_GUI> initializer;
};

```

like:

```
#include "catch2/catch.hpp"
#include "ScopedMessageThread.h"

TEST_CASE("foo")
{
    ScopedMessageThread t;
    REQUIRE_NOTHROW(somethingExecutingOnMessageThread());
}

```

Its still a bit tricky though, because you’ll need to use some WaitableEvents in order for your Catch-Thread not to end before the actual work on the message-thread is finished.
