-
-
Notifications
You must be signed in to change notification settings - Fork 649
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
testing private members - ability to write test cases in class bodies #76
Comments
This is the only thing I'm able to come up with: #define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
#include "doctest.h"
class A {
void private_method() { printf("hello!\n"); }
#ifdef DOCTEST_LIBRARY_INCLUDED
public:
static void test1() {
A a;
a.private_method();
}
#endif
};
DOCTEST_REGISTER_FUNCTION(A::test1, "test name")
// or like this:
// TEST_CASE("test name") { A::test1(); } The problem is that I need to create a global dummy variable outside of the class to force the execution of code before |
I'm closing this - not sure what else I could suggest |
Could this be solved using C++17 |
@JankoDedic turns out it is possible! there was one other problem but I managed to solve it, so now I'm thinking of what to call the new macro - perhaps |
That's amazing to hear! I just made it work a few minutes ago as well :). Not sure about the name, but |
I just pushed the change in the dev branch - here is how to use it (no matter if in a source or a header file): class my_type {
int data = 5;
TEST_CASE_CLASS("private test! no problem") {
my_type local;
CHECK(local.data == 2);
}
public:
my_type() = default;
TEST_CASE_CLASS("public test! doesn't matter") {
my_type local;
CHECK(local.data == 2);
}
}; |
Unfortunately this TEST_CASE_CLASS macro requires writing the test case inside the class body, which might be ok when you have a header only library, but it's not that good when you have cpp/hpp files, and you would have to include a bunch of heavy includes in the hpp just for the test case. But I think it should be possible to split it into two, something like this (POC code follows, this won't work with templates): #define DOCTEST_TEST_CASE_CLASS_DECLARE(name) \
static const int DOCTEST_CAT(name, _VAR); \
static void DOCTEST_CAT(name, _FUNC)()
#define DOCTEST_TEST_CASE_CLASS_DEFINE(name, decorators) \
const int DOCTEST_CAT(name, _VAR) = doctest::detail::regTest( \
doctest::detail::TestCase( \
DOCTEST_CAT(name, _FUNC), __FILE__, __LINE__, \
doctest_detail_test_suite_ns::getCurrentTestSuite()) * decorators); \
void DOCTEST_CAT(name, _FUNC)() Then you can do A different solution (I don't think this would need doctest support, I'm just mentioning this for possible users ending up here after a google search) that we use at my company (with google test, eww) is to have a second class (e.g. |
@u3shit In that case I'm reopening this so I don't forget about it! |
I'm curious that good old |
Also good old getter :) I suggest we close this due to several reasons
|
Here is a c++17 workaround template that people can use if they really want to test private members of a class #define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
#include <doctest/doctest.h>
template <typename T>
struct Inspect {
const T &self;
Inspect(const T &self) : self{self} {}
auto get();
};
class X {
private:
int data;
public:
X(int data) : data{data} {}
friend class Inspect<X>;
};
template <> auto Inspect<X>::get() {
return self.data;
}
TEST_CASE("private") {
X x(1337);
REQUIRE(Inspect(x).get() == 1337);
} |
Also adding forward declarations into the mix allows to create minimal macros: #define TEST_PRIVATE struct test_inspector_t; friend test_inspector_t;
#define TEST_PRIVATE_IMPL(x) struct x::test_inspector_t class testee_t
{
int m_private_field = 1;
TEST_PRIVATE
}; TEST_PRIVATE_IMPL(testee_t)
{
TEST_CASE_CLASS("private field")
{
testee_t testee;
CHECK(testee.m_private_field == 1);
}
}; Maybe similar macros can be added to doctest. |
Description
Some classes have private methods which cannot be conveniently tested through a public interface.
What is the recommended way to test a private method using doctest?
Extra information
The text was updated successfully, but these errors were encountered: