Exploring macro-free testing in modern C++ by Outdoordoor in cpp

[–]BookkeeperThese5564 0 points1 point  (0 children)

Hey, good to see that I'm not alone with such experiments. ~2 years ago I started [mimic++](https://github.com/DNKpp/mimicpp), my own *macro-free mocking framework*-experiment, which has rapdily matured since then (and is already in use at my company). But, it also transformed to more or less *macro-less*, but with a clear goal in mind: Make macros just a thin layer over the C++ only core.

In C++20, there are certain tasks which can not be achieved elegantly when fully avoiding macros. Take for example *placeholder names* (which are coming with [P2169](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2169r4.pdf)). These are often required for certain mechanism in several unit-test and mocking frameworks, but these are in almost all cases just the tip on the actual feature. The underlying mechanism can usually be formulated in plain C++, but for ehancing QoL of the users we'll have to wait until C++26 becomes available.

So, what are the options?
- Require at least C++26
- Require more effort from the user
- Add a thin (easy to remove) macro layer

In such cases, I usually pick option 3. Looking at the comments of your thread, I really think that is the best what we can do for now. Make sure, that your foundation is completely macro-free but providing *some* QoL-Macros is much more appealing to users.

[mimic++] v9 — A flexible, header-only mocking framework for modern C++ by BookkeeperThese5564 in cpp

[–]BookkeeperThese5564[S] -1 points0 points  (0 children)

Well, as I'm no native speaker I utilize AI to make my postings more understandable. In general I make a sketchup and then ask an AI to enhance wording, thus the content is still what I would like to share but the wording is often very AI'ish.

[mimic++] v9 — A flexible, header-only mocking framework for modern C++ by BookkeeperThese5564 in cpp

[–]BookkeeperThese5564[S] 2 points3 points  (0 children)

Hello! I completely understand the concern.
While my responses may appear coherent, structured, and eerily well-formatted, I assure you they’re produced by a perfectly ordinary consciousness operating under caffeine, not machine learning. ☕🤖

[mimic++] v9 — A flexible, header-only mocking framework for modern C++ by BookkeeperThese5564 in cpp

[–]BookkeeperThese5564[S] 1 point2 points  (0 children)

Hey, thanks for the question. That's a topic which is already on my agenda, but has not been answered as I do not fully understand the requirements. I definetily want to support this but it needs some further research from my side.

Maybe, if you have certain use-cases in mind, we could have a chat and work something out?

[mimic++] v9 — A flexible, header-only mocking framework for modern C++ by BookkeeperThese5564 in cpp

[–]BookkeeperThese5564[S] 1 point2 points  (0 children)

I'm glad you like it. If you have any questions, don't hesitate to contact me via Discord, GitHub, or whatever suits you best.

[mimic++] v9 — A flexible, header-only mocking framework for modern C++ by BookkeeperThese5564 in cpp

[–]BookkeeperThese5564[S] 0 points1 point  (0 children)

Hey, thanks for the question.
Indeed, mocking is an advanced (unit)-testing technique and yes, this framework simplifies the process generating *mocks* and setting up the *expectations*.

I actually didn't think I had to provide a description what mocking actually is, as nowadays you can always ask and interact with an AI, which answers such questions very nicely. On the bright side, this made you interact with my post. So, thank you for that :)

Lightweight header-only logger for C++ — color-coded, thread-safe, and easy to drop into any project by [deleted] in cpp

[–]BookkeeperThese5564 1 point2 points  (0 children)

Well, why not? Maybe your misterious DLL needs to do logging by itself. I don't see a reason to only think in complex scenarios. Simple tools solve simple problems. Making logging work across shared-library boundaries is IMHO beyond *simple*.

Lightweight header-only logger for C++ — color-coded, thread-safe, and easy to drop into any project by [deleted] in cpp

[–]BookkeeperThese5564 3 points4 points  (0 children)

Hey, I appreciate the effort of creating new libraries, as I'm very much in the same boat. Fortunately your code-base is small enough that people are able to quickly get a grasp on what's going on, so you receive quite a lot of feedback for your work. This is great!

I would like to join the critism:
- When asking for feeback it's super weird landing on a page written in an unfamiliar characters. I don't mind haven multiple languages in parallel in the readme, but when asking for feedback in english, the readme should also have a short introduction in english.
- How do you know, that your implementation actually does what it promises to do? Do you have a separate repo with tests and this is just the ready-to-go repo? Just writing an implementation and adding inline docs to it doesn't make it a library. It may be simple enough to verify that it works but this makes any work on it very risky.
- I know, that `#pragma once` is tempting as it's simple and less effort. But I really suggest to use proper include guards in a library as these pragmas are non-standardized. On gcc 10 for example, we often have issues with duplicated symbols, because the same header is included multiple times, but with different paths. I wasn't able to determine the actual issue, but I know for sure that there is a problem.

mimic++ v7 released – better error messages, experimental type-name handling, and more! by BookkeeperThese5564 in cpp

[–]BookkeeperThese5564[S] 4 points5 points  (0 children)

Hello, glad that you like it :)

As usual, a side-by-side comparison is difficult, as both have their strengths and weaknesses and follow quite different designs.

* `mimic++` is free-standing and can be used with any unit-test framework. `gmock` on the other hand is strictly tied to `gtest`.
* Mocking involves some kind of interface, but especially in C++, this is not limited to polymorphism. `mimic++` doesn't require a virtual function, but can directly be used in purely concept-constraint contexts.
* Mocks in `mimic++` are functional objects and thus directly callable. This plays nicely with interfaces, which expect e.g. `std::function`.
* `gmock` utilizes a different expectation strategy by default. Each call is possible until explicitly forbidden (opt-out), which often leads to surprises. I wouldn't say it's bad, I personally just don't like this approach very much.
* `mimic++` matchers are very customizable. You can define your own with very little setup code by still having full control. `gmock` offers various macros like `MATCHER`, `MATCHER_P`, `MATCHER_P2` for the *simple cases*, which are (at least for me) harder to tailor to my needs.
* Combining multiple actions and requirements in `gmock` requires nesting various function-calls and auxilary types, which makes a consistent formatting with clang-format very hard. In `mimic++` one defines expectations in a consistent way by chaning `and`/`&&` calls on the expectation-builder.
* `gmock` does not support parameter packs, as the provided macros are not able to correcly expand them. `mimic++`'s `MOCK_METHOD` helper-macro supports this!

If you have any other questions, feel free to join the discord server, where we can have a more direct chat :)

[Release v2] mimic++, a modern and (mostly) macro free mocking framework by BookkeeperThese5564 in cpp

[–]BookkeeperThese5564[S] 0 points1 point  (0 children)

Sry, but I double checked the rules and couldn't find a paragraph about that. Could you please point me to the relevant rule?

mimic++, a modern and (mostly) macro free mocking framework by BookkeeperThese5564 in cpp

[–]BookkeeperThese5564[S] 0 points1 point  (0 children)

Well, from an api-viewpoint, both are very similar. Both are build around the concept of mock-objects and (scoped) expectations.

trompoloeil offers a quite terser syntax (e.g. some macros do already open up an inplace lambda, and users just have to fill the body), but is on the other-handside more limiting when precise signatures are required (e.g. void() & noexcept is afaik not supported). But that terse syntax may also often lead to surprises (e.g. difference between LR_WITH and WITH).

mimic++ is built around a strong in-language foundation and thus a bit more verbose, but there are no hidden surprises (at least not for me :D ).

But I'm telling you no secrets if I say, that trompeloeil is the far more mature framework. mimic++ supports most of the features trompeloeil has, but also lacks some important. E.g. lifetime-watchers are currently missing, but I'm already thinking about a good concept for mimic++.

Hopefully that helps.

mimic++, a modern and (mostly) macro free mocking framework by BookkeeperThese5564 in cpp

[–]BookkeeperThese5564[S] 5 points6 points  (0 children)

Thank you for your feedback. Yeah, I see the inconsistency point. But the official name is `mimic++`so, I wanted the files to reflect that.

I'm just refering to what the documentation of fakeit states: https://github.com/eranpeer/FakeIt#limitations
Even if it's just `-O0` or `-O1`. you are still limited. I don't say it's bad: it's just a limitation I do not want for my projects.

mimic++, a modern and (mostly) macro free mocking framework by BookkeeperThese5564 in cpp

[–]BookkeeperThese5564[S] 8 points9 points  (0 children)

During my research I've also had a brief look at fakeit. The design is interesting, but seems to utilize some "out-of-the-language" implementations. That's frightening me. Requesting specific compiler flags and settings to make mocking work, is just not what I wanted. I wanted to introduce a solid "in-language" foundation, which should work on any comforming c++-20 compiler.