GithubHelp home page GithubHelp logo

dnkpp / mimicpp Goto Github PK

View Code? Open in Web Editor NEW
0.0 1.0 0.0 3.85 MB

A modern and (mostly) macro free mocking-framework

Home Page: https://dnkpp.github.io/mimicpp/

License: Boost Software License 1.0

CMake 1.64% C++ 98.36%
cpp20 macro-free mocking-framework templates

mimicpp's Introduction

mimic++, a modern and (mostly) macro free mocking framework

codecov Coverage Status Codacy Badge Codacy Badge Documentation


Author

Dominic Koepke
Mail: [email protected]

License

BSL-1.0 (free, open source)

          Copyright Dominic "DNKpp" Koepke 2024 - 2024
 Distributed under the Boost Software License, Version 1.0.
    (See accompanying file LICENSE_1_0.txt or copy at
          https://www.boost.org/LICENSE_1_0.txt)

Introduction

mimic++ is a c++20 mocking framework, which aims to offer a very natural end expressive syntax, without constantly resorting to macros. To be honest, macros cannot be completely avoided, but they can at least be reduced to a very minimum.

The one thing, that this framework does different than all other (or at least all I am aware of) mocking framework is, that mock objects explicitly are function objects, thus directly callable. It's simple and straight forward.

As I'm mainly working on template or functional-style code, I wanted something simpler than always creating explicit mock types for the simplest of use cases. So, mimicpp::Mock objects can directly be used as functional objects, but they can also be used as member objects and thus serve as actual member functions.

If you are curious, have a look at the documentation, investigate the examples folder or play around online at godbolt.org

Design Philosophy

The framework is designed with two core concepts in mind: Mocks and Expectations. Mocks can be used to define behaviour on a per test-case basis, without the necessity of creating dozens of types. The go-to example is, if you have a custom type, which somehow makes a connection to a concrete database, you do not want to setup an actual database connection during your test runs. You then simply install a database mock, which then yields the exact replies as it were defined for that particular case: the so called "Expectations".

So, Mocks and Expectations are going together hand in hand.

Additionally, users are able to create their own expectation policies easily and integrate them seamless into the rest of the framework. Be creative!

Extensibility

As already mentioned, users may invent their own expectations policies, but the framework doesn't stop there. In general this framework is designed to offer a robust foundation, which users can tailor for their needs.

Stringification

mimic++ can not provide stringification for any type out there, but it's often very useful to see a proper textual reprensentation of an object, when a test fails. mimic++ will use std::format for formattable types, but sometimes that is not, what we want, as users for example want to have an alternative stringification only for testing. Users can therefore add their specializations of the mimicpp::custom::Printer type and thus tell mimic++ how a given type shall be printed.

Custom specializations will always be prefered over any pre-existing printing methods, thus users may even override the stringification of e.g. ranges.

Test Framework Integration

Mocking frameworks usually do not exist for their own, as they are in fact just an advanced technice for creating tests. Instead, they should work together with any existing test framework out there. mimic++ provides the IReporter interface, which in fact serves as a bridge from mimic++ into the utilized test framework. mimic++ provides some concrete reporter implementations for well known test frameworks, but users may create custom adapters for any test framework or simply use the default reporter. For more details have a look into the reporting section in the documentation.

Always Stay Within The Language Definition

There are a lot of mocking frameworks, which utilize clever tricks and apply some compiler specific instructions to make the work more enjoyable. mimic++ does not! This framework will never touch the ground of undefined behaviour or tricks, which will only work under some circumstances, as this is nothing I want to support and maintain over a set of compilers or configurations. Unfortunatle this often leads to a less elegant syntax for users. If you need that, than this framework is probably not the right for you. Pick your poison :)

Basic Examples

Mocks themselves are very easy to create:

mimicpp::Mock<void()> myMock{};

This already is a fully functional Mock, which enables a member void operator() for which Expectations can be created.

mimicpp::ScopedExpectation myExpectation = myMock.expect_call();

The expect_call() member function initiates an expectation. Expectations are usually required to be fulfilled within the current (or deeper) scope. The ScopedExpectation then takes over the responsibility to check the Expectation, when that scope is left. Usually users do not need direct access to the expectations but still an unique name is required. To overcome that language limitation, an optional macro can be used:

SCOPED_EXP myMock.expect_call();

This effectively does the same job as before, but the macro takes over the burden creating an unique name for that expectation.

Given the previously created expectation, it is expected, that the call operator of myMock is called exactly once:

myMock();

Expectations can contain several requirements, e.g. times which indicates, how often an Expectation must be met. For more examples, have a look into the documentation or directly into the examples directory.

Special Acknowledgement

This framework is highly inspired by the well known trompeloeil, which I have used myself for several years now. It's definitly not bad, but sometimes feels a little bit dated and some macros do not play very well with formatting tools and the like. If you need a pre-c++20 mocking-framework, you should definitly give it a try.

Fun fact: mimic++ uses trompeloeil for it's own test suite :D

Documentation

The documenation is generated via doxygen. Users can do this locally by enabling both, the MIMICPP_CONFIGURE_DOXYGEN and MIMICPP_CONFIGURE_DOXYGEN, cmake options and building the target mimicpp-generate-docs manually.

The documentation for the main branch is always available on the github pages; for the development branch it is also available on the dev-gh-pages branch, but unfortunatly not directly viewable on the browser. Every release has the generated documentation attached.

Installation

This framework is header-only and completely powered by cmake, thus the integration into a cmake project is straight-forward.

target_link_libraries(
    <your_target_name>
    PUBLIC
    mimicpp::mimicpp
)

Users can either pick a commit in the main branch or a version tag and utilize the cmake FetchContent module:

include(FetchContent)

FetchContent_Declare(
    mimicpp
    GIT_REPOSITORY https://github.com/DNKpp/mimicpp
    GIT_TAG        <any_commit_hash_or_tag>
)

FetchContent_MakeAvailable(mimicpp)
# do not forget linking via target_link_libraries as shown above

As an alternative, I recommend the usage of CPM, which is a featureful wrapper around the FetchContent functionality:

include(CPM.cmake) # or include(get_cpm.cmake)

CPMAddPackage("gh:DNKpp/mimicpp#<any_commit_hash_or_tag>")
# do not forget linking via target_link_libraries as shown above

Testing

mimic++ utilizes a strict testing policy, thus each official feature is well tested. The effect of those test-cases are always tracked by the extensive ci, which checks the compilation success, test cases outcomes and coverage on dozens of different os, compiler and build configurations.

The coverage is generated via gcov and evaluated by codacy, codecov and coveralls.

Windows

OS Compiler c++-20 c++-23
Windows 2022 msvc x x
Windows 2022 clangCl x x

Linux

Compiler libstdc++ libc++ c++-20 c++-23
clang-17 x x x x
clang-18 x x x x
gcc-13 x - x x
gcc-14 x - x x

MacOs

Compiler libstdc++ libc++ c++-20 c++-23
AppleClang-17.0.6 - x x x

As new compilers become available, they will be added to the workflow, but older compilers will probably never be supported.

mimicpp's People

Contributors

dnkpp avatar

Watchers

 avatar

mimicpp's Issues

Finalizers

Finalizers can be applied only once per expectation.

  • expectation_policies::InitFinalizer
  • expectation_policies::ReturnsResultOf
  • expectation_policies::Throws

Factories

  • finally::throws
  • finally::returns
  • finally::returns_result_of
  • finally::returns_apply_result_of<ns...>
  • finally::returns_apply_all_result_of
  • finally::returns_param<n>
  • finally::returns_params<ns...>

Improve reporter

  • match result printing
  • add default reporter for standalone usage

Matchers

Matchers can be used:

  • directly as expectation argument
  • as explicit expectation
    • expect::arg<n>
    • expect::args<ns...>
    • expect::all_args

Generic Matchers:

  • matcher::PredicateMatcher
    • matcher::InvertiblePolicy
    • matcher::ConjunctionPolicy
    • matcher::DisjunctionPolicy

Basic Matchers

  • matches::_
  • matches::eq
  • matches::ne
  • matches::lt
  • matches::le
  • matches::gt
  • matches::ge
  • matches::approx
  • matches::predicate

String Matchers

  • matches::str::eq
  • matches::str::starts_with
  • matches::str::end_with
  • matches::str::contains
  • matches::str::matches_regex

Range matchers

  • matches::range::eq
  • matches::range::unordered_eq
  • matches::range::is_sorted
  • matches::range::is_empty
  • matches::range::has_size
  • matches::range::elements

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.