Мой код структурирован, как показано ниже:
namespace A{
class baseClass{
template<typename t> static ::boost::shared_ptr<t> create_obj();
};
}
namespace A{
namespace B{
class DerivedClass1 : public baseClass {
void create_obj(){...};
}
}
}
namespace A{
namespace C{
class DerivedClass2 : public baseClass {
void create_obj(){...};
}
}
}
Существует базовый класс и около 5-6 производных классов, которые находятся в разных пространствах имен. Я пытаюсь написать тест для create_obj () с использованием среды тестирования Google, используя тест с параметризацией типа, поскольку метод должен быть протестирован для всех производных классов. Мой тестовый код:
#include "gtest/gtest.h"#include "baseClass.h"#include "DerivedClass1.h"#include "DerivedClass2.h"
using namespace A;
using namespace B;
using namespace C;
template<typename T> class sample_test : public ::testing::Test
{
protected:
boost::shared_ptr<TypeParam> = create_obj();
};
TYPED_TEST_CASE_P(sample_test);
TYPED_TEST_P(sample_test, firstTest)
{
//do some testing
}
REGISTER_TYPED_TEST_CASE_P(sample_test, firstTest);
typedef ::testing::Types<DerivedClass1, DerivedClass2> tTypes;
INSTANTIATE_TYPED_TEST_CASE_P(mytest, sample_test, tTypes);
Этот код выдает некоторую ошибку шаблона, так как не знает, какую функцию create_obj () вызывать.
Поэтому я пытаюсь написать сценарий переключения или сценарий if-else в моем тесте, который будет вызывать метод из правильного пространства имен. Что-то вроде
template<typename T> class sample_test : public ::testing::Test
{
protected:
switch(T)
{
case DerivedClass1:
//Call method like A::B::create_obj()
case DerivedClass2:
//Call method like A::C::create_obj()
}
};
Но я, очевидно, не могу дать T в качестве параметра в случае переключения или даже в сценарии if-else. Есть ли способ достичь этого?
П.С .: Очень жаль, но я не могу опубликовать код онлайн. Я надеюсь, что этого будет достаточно.
Судя по опубликованному коду, вы можете исправить свой тестовый код, указав пространства имен непосредственно при регистрации типов, например:
typedef ::testing::Types<A::B::DerivedClass1, A::C::DerivedClass2> tTypes;
Однако, поскольку вы не публиковали MCVE, я не могу быть на 100% уверен, что он будет работать. Если это не так, вы можете использовать черты типа для различения разных типов во время компиляции:
if (std::is_same<T, A::B::DerivedClass1>::value)
//Call method like A::B::create_obj()
else if (std::is_same<T, A::C::DerivedClass2>::value)
//Call method like A::C::create_obj()
...
Для получения дополнительной информации см. Документацию: http://en.cppreference.com/w/cpp/types/is_same
Я не знаю почему, но ни std :: is_same, ни boost :: is_same не сработали. Оба выдавали ошибку компиляции «Синтаксическая ошибка: оператор if». Но в конечном итоге сработал следующий код, предложенный @Ulrich Eckhardt.
template<typename T> class sample_test : public ::testing::Test
{
protected:
boost::shared_ptr<T> testObj;
testObject = T::create_obj();
};