Как определить переменные в приборах Googletest, если у них нет конструктора по умолчанию? - PullRequest
0 голосов
/ 04 апреля 2020

У меня есть следующее


#include <semsim/Subject.h>
#include <semsim/Triple.h>
#include "gtest/gtest.h"

class TripleTests : public ::testing::Test {
public:

    std::string subject_str;
    semsim::Subject subject;

    void SetUp() override {
        subject_str = "./MyModel#metaid_0";
        subject = semsim::Subject(subject_str);
    }
};

TEST_F(TripleTests, TestSubjectMetaId) { // this line causes the error
    std::cout << subject << std::endl;
}

Чтобы определить переменные (для последующего использования в TEST_F функциях), они должны быть созданы в области видимости класса и затем заполнены значением в SetUp метод. Это потому, что я не могу передать subject_str на Subject на уровне класса. Однако, если вы создаете экземпляр переменной на уровне класса, она использует конструктор по умолчанию, а мой класс не имеет (и не нуждается) в нем. Вот жалоба от моей IDE:

Call to implicitly-deleted default constructor of 'TripleTests' because field 'subject' has no default constructor

Поэтому мой вопрос: без необходимости определять конструктор по умолчанию, как бы я создал предметный объект внутри класса TripleTest, чтобы его можно было использовать в TEST_F функции? Или необходимо использовать конструктор по умолчанию в Suject, чтобы я мог создать его в тестовом приспособлении?

Для справки заголовок Subject выглядит следующим образом:

    class Subject {
    private:
        std::string metaId;

    public:

        explicit Subject(std::string metaId) : metaId(std::move(metaId)) {};

        const std::string &getMetaId() const;

        bool operator==(const Subject &rhs) const;

        bool operator!=(const Subject &rhs) const;

        friend std::ostream &operator<<(std::ostream &os, const Subject &subject);
    };

}

Редактировать

Ответ @Tomasz


class TripleTests : public ::testing::Test {
public:

    std::string subject_str;
    semsim::Subject subject;
    // alternative 1
    TripleTests()  {
        this->subject_str = "./MyModel#metaid_0";
        semsim::Subject s(subject_str);
        this->subject = s;
    }

    // alternative 2
    TripleTests()  {
        this->subject_str = "./MyModel#metaid_0";
        this->subject = semsim::Subject(subject_str);
    }

приводит к

Constructor for 'TripleTests' must explicitly initialize the member 'subject' which does not have a default constructor. Isn't the line `this->subject = s` initialising the member `subject`? 

1 Ответ

1 голос
/ 04 апреля 2020

Вы должны использовать конструктор прибора вместо SetUp() для инициализации членов в списке инициализатора:

class TripleTests : public ::testing::Test {
public:

    std::string subject_str;
    semsim::Subject subject;

    TripleTests() 
        : subject_str("./MyModel#metaid_0")
        , subject(subject_str)
    {
    }
};
...