I'm having lots of trouble to make this work and I'm at a point that I don't know what else to try (I've search through the bug list and found a few solutions but they don't work in my case)
The "design" of the classes is the following:
TestClass is the one being tested
** Uses a Provider interface to retrieve abstract Source objects
TestProvider is a test implementation of the Provider interface to try to make the tests work (based on #40)
** Has a CreateRaw function that can be mocked by the tests
MySQLSource is a particular Source implementation
So here's a sample code with the TEST_CASE being what I've tried to no avail:
//#define CATCH_CONFIG_MAIN
//#define _SILENCE_CXX17_UNCAUGHT_EXCEPTION_DEPRECATION_WARNING
//#include <catch.hpp>
#include <string>
#include <vector>
class Source
{
public:
virtual std::vector< std::string > list_tables() = 0;
};
class MySQLSource : public Source
{
public:
//virtual ~MySQLSource() = default;// uncomment for last test
MySQLSource(std::string const &, std::string const &, std::string const &, std::string const &);
std::vector< std::string > list_tables();
};
class Provider
{
public:
virtual std::unique_ptr< Source > provide_mysql() = 0;
};
class TestProvider
{
public:
std::unique_ptr< Source > provide_mysql()
{
return std::make_unique< Source >(CreateRaw());
}
MySQLSource *CreateRaw()
{
return nullptr;
}
};
class TestClass
{
public:
TestClass(Provider *p) : _p(p) {}
std::vector< std::string > TestMethod()
{
auto source = _p->provide_mysql();
return source->list_tables();
}
private:
Provider *_p;
};
TEST_CASE("Returning a make unique gives the error 'attempting to reference a deleted function'")
{
Mock< Provider > provider;
TestClass to_test(&provider.get());
When(Method(provider, provide_mysql)).Return(std::make_unique< MySQLSource>("", "", "", ""));
}
TEST_CASE("DOing a return of a make unique gives the error (see message below)")
{
Mock< Provider > provider;
TestClass to_test(&provider.get());
When(Method(provider, provide_mysql)).Do([] { return std::make_unique< MySQLSource >("", "", "", ""); });
}
/*
error C2664: 'fakeit::MethodStubbingProgress<R,const std::string &,const std::string &,const std::string &,const std::string &> &fakeit::MethodStubbingProgress<R,const std::string &,const std::string &,const std::string &,const std::string &>::Do(std::function<R (const std::string &,const std::string &,const std::string &,const std::string &)>)': cannot convert argument 1 from '____C_A_T_C_H____T_E_S_T____0::<lambda_eab2a539bb20cf804eb02bed96cfb852>' to 'std::function<R (const std::string &,const std::string &,const std::string &,const std::string &)>'
with
[
R=std::unique_ptr<studio::Source,std::default_delete<studio::Source>>
]
message : No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
message : see declaration of 'fakeit::MethodStubbingProgress<R,const std::string &,const std::string &,const std::string &,const std::string &>::Do'
with
[
R=std::unique_ptr<studio::Source,std::default_delete<studio::Source>>
]
*/
TEST_CASE("Returning a raw MySQLSource through a CreateRaw and a partial implemented Provider compiles but errors with 'Cant mock the destructor. No virtual destructor was found'")
{
Mock< TestProvider > provider;
TestClass to_test(&provider.get());
When(Method(provider, CreateRaw)).Return(new MySQLSource("", "", "", ""));
}
TEST_CASE("Returning the pointer to the mocked source through CreateRaw and a partial implemented Provider compiles but errors with 'Cant mock the destructor. No virtual destructor was found")
{
Mock< TestProvider > provider;
TestClass to_test(&provider.get());
Mock< MySQLSource > the_source;
When(Method(provider, CreateRaw)).Return(&the_source.get());
}
TEST_CASE("Returning the pointer to the mocked source through CreateRaw and a partial impemented Provider compiles but crashes due to bad memory if the virtual destructor of the MySQLSource is added and faked")
{
Mock< TestProvider > provider;
TestClass to_test(&provider.get());
Mock< MySQLSource > the_source;
Fake(Dtor(the_source)); // uncomment the virtual destructor of MySQLSource
When(Method(provider, CreateRaw)).Return(&the_source.get());
}
Overall I cannot even get to the main issue which is to be able to return a mocked or spied MySQLSource through the Provider using a unique pointer
I'm having lots of trouble to make this work and I'm at a point that I don't know what else to try (I've search through the bug list and found a few solutions but they don't work in my case)
The "design" of the classes is the following:
TestClass is the one being tested ** Uses a Provider interface to retrieve abstract Source objects
TestProvider is a test implementation of the Provider interface to try to make the tests work (based on #40) ** Has a CreateRaw function that can be mocked by the tests
MySQLSource is a particular Source implementation
So here's a sample code with the TEST_CASE being what I've tried to no avail:
Overall I cannot even get to the main issue which is to be able to return a mocked or spied MySQLSource through the Provider using a unique pointer
Any thoughts or ideas? Thanks in advance