Skip to content

Support test-specific header injection for generated mock files #1138

@JannisRln

Description

@JannisRln

Feature request

First of all, thank you for Ceedling/CMock. It is a great framework and very useful for embedded C testing. I really appreciate the work that has gone into making unit testing in C more practical.

I would like Ceedling/CMock to support injecting additional header files from a specific test file into generated mock files, without applying those includes globally to every generated mock.

Current behavior / limitation

CMock already provides include-related configuration options such as:

#:includes: []                   # You can add additional includes here, or specify the location with the options below
:includes_h_pre_orig_header: ['bds_canopen_obj_api_for_mock.h']
#:includes_h_post_orig_header: []
#:includes_c_pre_header:  []
#:includes_c_post_header:  []

These options are useful, but they appear to apply broadly across generated mocks/tests. In my case, adding a header this way injects it into each test/mock generation context.

This can lead to unwanted includes, unnecessary dependencies, and possible conflicts in tests that do not need those headers.

Problem

Some tests require mock-specific or test-specific headers, for example to provide:

  • additional type definitions
  • macros
  • test-only configuration
  • platform-specific declarations
  • compatibility wrappers for a specific mocked interface

However, these headers should only be included for the mock used by a particular test file, not globally for all generated mocks.

Manually editing generated mock files is not practical because those files are regenerated by Ceedling/CMock.

Proposed solution

Add a way for a test file to declare extra includes for a specific generated mock.

For example, using an annotation-style directive:

// In test_driver.c

#include "unity.h"
#include "mock_driver.h"

// Desired feature:
// inject only into mock_driver.c / mock_driver.h for this test
// @mock_include "test_driver_types.h"

Or with a more explicit mock target:

// @mock_include mock_driver "test_driver_types.h"

As an alternative, this could use a macro-like syntax similar to the already supported TEST_INCLUDE_PATH(...) mechanism for test include paths:

// In test_driver.c

#include "unity.h"
#include "mock_driver.h"

// Desired feature:
// inject only into mock_driver.c / mock_driver.h for this test
TEST_MOCK_INCLUDE("mock_driver.h", "test_driver_types.h")

or, if the mock name should be used instead of the mock header:

TEST_MOCK_INCLUDE(mock_driver, "test_driver_types.h")

A more location-specific variant could also mirror the existing CMock include placement options:

TEST_MOCK_INCLUDE_H_PRE_ORIG_HEADER(mock_driver, "test_driver_types.h")
TEST_MOCK_INCLUDE_H_POST_ORIG_HEADER(mock_driver, "test_driver_types.h")
TEST_MOCK_INCLUDE_C_PRE_HEADER(mock_driver, "test_driver_config.h")
TEST_MOCK_INCLUDE_C_POST_HEADER(mock_driver, "test_driver_config.h")

This would cause CMock to inject the header only into the generated mock file associated with that test/mock combination, instead of injecting it into every mock.

Desired behavior
Existing global CMock include options continue to work as they do today.
Additional includes can be scoped to a specific test file and mock.
Includes are not injected into unrelated generated mocks.
Generated files do not need to be manually edited.
The feature supports the same include locations already available globally:

:includes_h_pre_orig_header
:includes_h_post_orig_header
:includes_c_pre_header
:includes_c_post_header

Benefit

This would make it easier to test embedded C projects where some mocks need test-specific helper headers, without polluting every generated mock with unnecessary includes or causing include conflicts in unrelated tests.

Thanks again for maintaining Ceedling/CMock. It is a valuable framework, and this feature would make it even more flexible for complex embedded test setups.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions