Как издеваться над классом в функции, которую я пытаюсь протестировать?

#c #constructor #mocking #gmock

Вопрос:

Я пытаюсь протестировать функцию, подобную приведенной ниже, в Provider.cpp,

 SomeType::Data Provider::getData()
{
    const Param param();
    SomeType wanted_data = SomeType::Data(Creator{}(param));
    return wanted_data;
}
 

Но создание создателя в getData() затрудняет тестирование этой функции.

К вашему сведению, Provider.h похож на

 class Provider {
    public:
        SomeType::Data getData();
    
        // constructor/destructor
        Provider(Systemamp; system);
        ~Provider();
    
    private:
        Systemamp; m_system;
};
 

В то время как у Создателя есть следующее в Creator.h

 class Creator {
    public:
        //operator function overload?
        virtual SomeType::Data operator()(Param param) {
            SomeType::Data data = ...;//create data
            return data;
        }

        // constructor/destructor
        Creator();
        virtual ~Creator(){};
};
 

Я смотрел в течение нескольких часов, и мне кажется, что издевательство над созданием объекта в функции кажется невозможным. Если я все еще хочу протестировать эту функцию и создавать объект DataCreator всякий раз, когда я вызываю getData (), как я могу это сделать? (если это возможно…)

Я читал в Google, что в таком случае вы можете использовать указатель или ссылку в конструкторе, но я не уверен, что это значит… :'(

Комментарии:

1. Похоже , вы используете бетон Creator , который не позволит вам использовать производный класс. Вам нужно будет изменить свой источник , чтобы взять a Creator* , что позволит вам предоставить любой Creator из них или ваш высмеянный класс.

2. Похоже, вы используете тестирование после факта (TAD, Тестирование после разработки), а не тестирование для руководства разработкой (TDD, Разработка на основе тестов). Это тот момент, когда вы обнаруживаете, что реализация беспечно нарушила SOLID, не поддается модульному тестированию и нуждается в доработке, чтобы обеспечить последующее тестирование. TDD оказывает давление на разработчика, чтобы он принял SOLID с самого начала, вместо того, чтобы проводить его рефакторинг.

3. Ну, если код другой, мне трудно сказать, как его следует изменить. Ваш создатель здесь также статически типизирован, поэтому я не уверен, в чем смысл того, чтобы он operator() был виртуальным. Я боюсь, что вы создали фрагмент, который слишком лишен фактических деталей, чтобы дать вам полезный совет. Кроме того, TDD переоценен 😉

4. @Eljay Я должен сказать, что мой комментарий был связан только с семейством языков Си. Для чего-то вроде python, набирающего утку, TDD, вероятно, необходим.

5. И, по мнению @Eljay, многое из того, что может потребовать модульного тестирования на других языках, будет выглядеть как грубые ошибки компиляции в C .