ThrowTheSwitch / CMock

CMock - Mock/stub generator for C
http://throwtheswitch.org
MIT License
684 stars 276 forks source link

No function prototypes found in C++ header #472

Open lipi opened 7 months ago

lipi commented 7 months ago

According to https://github.com/ThrowTheSwitch/CMock/blob/master/docs/CMock_Summary.md the following example

% cat x.h
namespace MyNamespace {
    class MyClass {
        static int DoesSomething(int a, int b);
    };
}

should generate

void MyNamespace_MyClass_DoesSomething_ExpectAndReturn(int a, int b, int toReturn);

but the actual mock is missing the declaration.

Running this command:

% ruby lib/cmock.rb x.h
Creating mock for x...
WARNING: No function prototypes found by CMock in x

The generated mock is empty:

% cat mocks/Mockx.h
/* AUTOGENERATED FILE. DO NOT EDIT. */
#ifndef _MOCKX_H
#define _MOCKX_H

#include "unity.h"
#include "x.h"

/* Ignore the following warnings, since we are copying code */
#if defined(__GNUC__) && !defined(__ICC) && !defined(__TMS470__)
#if __GNUC__ > 4 || (__GNUC__ == 4 && (__GNUC_MINOR__ > 6 || (__GNUC_MINOR__ == 6 && __GNUC_PATCHLEVEL__ > 0)))
#pragma GCC diagnostic push
#endif
#if !defined(__clang__)
#pragma GCC diagnostic ignored "-Wpragmas"
#endif
#pragma GCC diagnostic ignored "-Wunknown-pragmas"
#pragma GCC diagnostic ignored "-Wduplicate-decl-specifier"
#endif

#ifdef __cplusplus
extern "C" {
#endif

void Mockx_Init(void);
void Mockx_Destroy(void);
void Mockx_Verify(void);

#ifdef __cplusplus
}
#endif

#if defined(__GNUC__) && !defined(__ICC) && !defined(__TMS470__)
#if __GNUC__ > 4 || (__GNUC__ == 4 && (__GNUC_MINOR__ > 6 || (__GNUC_MINOR__ == 6 && __GNUC_PATCHLEVEL__ > 0)))
#pragma GCC diagnostic pop
#endif
#endif

#endif
mvandervoord commented 7 months ago

Hi. This feature isn't part of the previous release. It's in the about-to-be-released 2.6.0. You can clone the repo if you'd like access to it immediately (make sure you include submodules). Alternatively, you can download the zip file generated by github (in which case you'll need to also grab the zip files for Unity and CException, if you're using it)

lipi commented 7 months ago

I am using the 2.6.0 branch afaik:

% git status
On branch cmock_2_6_rc
lipi commented 7 months ago

Digging into https://github.com/ThrowTheSwitch/CMock/blob/master/lib/cmock_header_parser.rb#L334 it seems that

Adding public: visibility and a non-static method to the example code:

namespace MyNamespace {
    class MyClass {
        public:
        static int DoesSomething(int a, int b);
        int NonStatic(int a);
    };
}

creates a mock for DoesSomething only:

using namespace MyNamespace;
#define MyNamespace_MyClass_DoesSomething_ExpectAndReturn(a, b, cmock_retval) MyNamespace_MyClass_DoesSomething_CMockExpectAndReturn(__LINE__, a, b, cmock_retval)
void MyNamespace_MyClass_DoesSomething_CMockExpectAndReturn(UNITY_LINE_TYPE cmock_line, int a, int b, int cmock_to_return);

The documentation could be a bit clearer. It says:

Simply use CMock to mock the static member methods and a C++ mocking framework to handle the virtual methods. (Yes, you can mix mocks from CMock and a C++ mocking framework together in the same test!)

It would help if it explicitly stated that non-static methods need a C++ mocking framework, for example

Simply use CMock to mock the static member methods and a C++ mocking framework to handle the virtual methods. (Yes, you can mix mocks from CMock and a C++ mocking framework together in the same test!) Non-static methods can be mocked by a C++ mocking framework.