I am working on an embedded C project where there is a function used to initialise a module's (foo) context object handle. Thus when testing using the Ceedling I have used this initialising function in the set up:

#include "unity.h"
#include "mock_bar.h"
#include "foo.h"

static foo_handle s = NULL;

void setUp(void)
{
    s = foo_init(&bar_assertAlert, &bar_releaseAlert);
}

As you can see the foo_init() function requires two handles to functions from another module (bar). This allows those functions to be called in the case of an asychronous event. The bar module is mocked by Ceedling so that I can test for the use of those functions in some tests.

However, because the bar functions are mocked the setUp reports as a test fail everytime as the init function actually calls the bar_releaseAlert to ensure it's initial state.

"Function bar_releaseAlert.  Called more times than expected."

I can add an "ignore" to the setup, as below, but it strikes me as wrong to have test type code in a set up or tear down. Maybe that assumption is wrong though?

void setUp(void)
{
    bar_releaseAlert_Ignore();
    s = foo_init(&bar_assertAlert, &bar_releaseAlert);
}

Or is this poor design on my part? How can I test a module that uses a mocked function where the setup calls that mocked function?

up vote 2 down vote accepted

As a fellow Ceedling user I've wrestled with these ideas before. Ideally, you would want to avoid direct testing in the setUp functions, but because of how Ceedling and Cmock work just using Expect and Ignore in setUp is acceptable as it's more controlling the mocks then testing in this phase.

One of the great thing about Cmock is it will force you to take into account every time a mocked function although then you run into situations like this where you'll have to either Expect or Ignore when it may not be the focus of what you want to test.

If you call bar_releaseAlert anywhere else in your tests, I would recommend using bar_releaseAlert_Expect as Ignore will ignore it until you Expect it which may not be what you want.

void setUp(void)
{
    bar_releaseAlert_Expect(); //Expect instead of Ignore if used elsewhere
    s = foo_init(&bar_assertAlert, &bar_releaseAlert);
}

Another option is using the fake_function_framework plugin instead of cmock which you can check if functions were called and how many times a function was called which may work better for what you are doing.

As a heads up how unity and ceedling work does allow for tests in both the setUp & tearDown and it affects how you may think Ceedling works for example, tearDown will not be called if a test is Ignored.

Disclaimer: I am by no means an experienced software developer or tester, nor have I worked with ceedling for a very long time. This being said, here are my thoughts on the matter:

If the initialising function isn't too complex for this, you could also try to emulate its core behaviour in setUp without actually calling anything. IMO calling a tested module's function in setUp has the additional disadvantage of you actually wanting to TEST that function and not just USE it. E.g. if you call the initialising function in setUp and it changes, all your tests may fail because of this and it might be hard to find the reason (different functions might throw different failures at you).

In my tests I've simply extracted the necessary stuff from the init functions and then tested as if nothing happened. Works so far.

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.