Создание экземпляра приложения и виджета Qt в Googletest приводит к ошибке утверждения заголовка __acrt_first_block == - PullRequest
1 голос
/ 01 августа 2020

Я создаю простое оконное приложение Qt с помощью CMake и решил использовать googletest для модульного тестирования. К сожалению, при создании виджета главного окна в рамках одного теста я иногда получаю сообщение об ошибке утверждения: __acrt_first_block == header. Я уже установил все CMakeLists для использования режима времени выполнения / MTd (как это делает тестовая библиотека Google, set(CMAKE_CXX_FLAGS_DEBUG "/MTd").

Окно сообщения об ошибке утверждения приводит меня к комментарию в источнике gtest, в котором говорится: // We create the exception message on the heap because VC++ prohibits creation of objects with destructors on stack in functions using __try (see error C2712).

Очевидно, что каждый объект Qt определяет собственный деструктор, так что проблема здесь. Но как заставить эти тесты работать? Могу ли я каким-то образом создать экземпляр своего mainwindow глобально один раз в tests. cpp file, а не индивидуально в каждом тесте?

class CalcTests : public testing::Test
{
protected:
    Calc* calc = nullptr;
    
    void SetUp() override
    {
        calc = new Calc{};
    }

    void TearDown() override
    {
        delete calc;
    }
};

// A sample test...
TEST_F(CalcTests, sin_pi_6)
{
    //auto calc = std::make_unique<Calc>(nullptr);
    calc->menuViewScientificTriggered(); // just in case

    const double pi_rounded = disp_rounding(std::numbers::pi).toDouble();
    calc->getCurrDisplay()->setText(disp_rounding(pi_rounded / 6));

    calc->sinClicked();
    const QString actual{ calc->getCurrDisplay()->text() };
    const QString expected{ "0.5" };

    ASSERT_EQ(actual, expected) << "\n\n\n"
                    << "Expected: " << expected.toStdString() << "\nActual: " << actual.toStdString();
}

Я также читал, что шаблоны могут вызывать сбой этого утверждения. Но в моем случае их всего два, и они довольно простые. Они не выделяют память в куче явно, но я прилагаю образец источника для справки:

template<typename Float>
bool nearly_equal(const Float a, const Float b, const Float eps_factor)
    requires std::is_floating_point_v<Float>
{
    const auto abs_a = std::abs(a);
    const auto abs_b = std::abs(b);
    
    return std::abs(abs_a - abs_b)
        <= std::numeric_limits<Float>::epsilon() * eps_factor;
}
...