HippoMocks: издевательский boost::chrono::steady_clock::now

У меня есть код:

boost::system::error_code clock_error;
const boost::chrono::steady_clock::time_point START = 
boost::chrono::steady_clock::now(clock_error);

и я хочу высмеять функцию now(), чтобы мой тестовый код содержал следующее:

boost::chrono::steady_clock::time_point start(boost::chrono::seconds(0));
boost::system::system_error clock_error(1, BOOST_CHRONO_SYSTEM_CATEGORY, "foo");
mocks.ExpectCallFuncOverload( (boost::chrono::steady_clock::time_point (boost::chrono::steady_clock::*) (boost::system::error_code& clock_error))
                                        &boost::chrono::steady_clock::now)    
                    .With(Out(clock_error))
                    .Return(start);

но это не компилируется. Я получаю эту ошибку:

ошибка: нет совпадений, преобразующих функцию «сейчас» в тип 'boost::chrono::steady_lock::time_point (класс boost::chrono::steady_lock::)(class boost::system::error_code&) {он же class boost::chrono::time_pointboost::chrono::steady_lock (класс boost::chrono::steady_lock::)(класс boost::system::error_code&)}’ макеты.ExpectCallFuncOverload(

В файле включено из...

примечание: кандидаты: static boost::chrono::steady_lock::time_point boost::chrono::steady_lock::now (boost::system::error_code&)

   static BOOST_CHRONO_INLINE time_point  now(system::error_code & ec);

                                          ^

../../../KACotsCode/boost/boost/chrono/system_clocks.hpp:162:46: примечание: статический импульс::chrono::steady_lock::time_point boost::chrono::steady_clock::now() статическая BOOST_CHRONO_INLINE time_point now() BOOST_NOEXCEPT;

                                          ^

Может ли кто-нибудь обнаружить проблему?

Попробуйте заменить (boost::chrono::steady_clock::*) на *? В любом случае это статическая функция, а не функция-член. И еще, пожалуйста, не издевайтесь над часами? Вместо этого вы можете использовать C++ по назначению и предоставить свой собственный тип часов, совместимый с хронометражом, в тестовых сборках. Но отнеситесь к этому с недоверием: я просто никогда не понимал привлекательности насмешек. Вместо этого у меня есть просто отдельные модули для тестирования. И используйте статическую композицию типов для тестов интеграционного типа.

sehe 24.07.2024 21:37

Вот концепция Часов из стандартной библиотеки для справки.

sehe 24.07.2024 22:15

Изменение (boost::chrono::steady_lock::*) на просто (*) не имело никакого значения.

zephod 25.07.2024 17:21
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
3
55
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я посмотрел на HippoMocks. Это очень высокотехнологичная штука. Я бы, наверное, не стал доверять этому рабочему коду, поскольку он очень навязчив и совершенно недокументирован¹

Тем не менее, он делает некоторые впечатляющие вещи с GCC и, судя по коду, с MSVC:

Live On Compiler Explorer

#define BOOST_CHRONO_HEADER_ONLY
#include "https://raw.githubusercontent.com/dascandy/hippomocks/master/HippoMocks/hippomocks.h"
#include <boost/chrono.hpp>
#include <iostream>
namespace chrono = boost::chrono;
using Clock      = chrono::steady_clock;

int main() {
    MockRepository mocks;

    boost::system::error_code clock_error = make_error_code(boost::system::errc::file_exists);

    mocks
        .ExpectCallFunc(Clock::now) //
        .With(Out(clock_error))     //
        .Return(Clock::time_point::max());
    auto START = Clock::now(clock_error);

    std::cout                            //
        << clock_error.message() << ": " //
        << std::hex << START.time_since_epoch().count() << std::endl;
}

Печатает ожидаемое

File exists: 7fffffffffffffff

БОНУС: издание «Путешественник во времени»

Возвращаясь к 2015 году (Boost 1.59 от 13 августа и GCC 4.8.5 от 23 июня):

Live On Compiler Explorer²

#define BOOST_CHRONO_HEADER_ONLY
#include "https://raw.githubusercontent.com/dascandy/hippomocks/master/HippoMocks/hippomocks.h"
#include <boost/chrono.hpp>
#include <iostream>
namespace chrono = boost::chrono;
using Clock      = chrono::steady_clock;

int main() {
    std::cout << "Boost version: " << BOOST_VERSION << std::endl;
    std::cout << "GCC version: " << __VERSION__ << std::endl;
    MockRepository mocks;

    boost::system::error_code clock_error = make_error_code(boost::system::errc::file_exists);

    mocks
        .ExpectCallFunc(static_cast<Clock::time_point (&)(boost::system::error_code&)>(Clock::now)) //
        .With(Out(clock_error))                                                                     //
        .Return(Clock::time_point::max());
    auto START = Clock::now(clock_error);

    std::cout                            //
        << clock_error.message() << ": " //
        << std::hex << START.time_since_epoch().count() << std::endl;
}

Как вы правильно догадались, вам необходимо явно указать тип перегруженной функции. Что еще более важно, HippoMocks не любит, когда вы передаете здесь указатель на функцию, поэтому обязательно указывайте регистр ссылки на функцию: static_cast<Clock::time_point (&)(boost::system::error_code&)>(Clock::now)

Доказательство пудинга:

Boost version: 105900
GCC version: 4.8.5
File exists: 7fffffffffffffff


¹ разработчики полагают, что каким-то образом «к сожалению, краткие документы ограничивают доступ и препятствуют прогрессу некоторых разработчиков» [так в оригинале]

² Compiler Explorer не может выполнить код, потому что Система Boost стала доступна только для заголовков в Boost 1.69.0

Я не знаю, как это у вас скомпилировано. now() — это перегруженная функция, поэтому hippomocks требует, чтобы вы вызывали ExpectCallFuncOverload, а не ExpectCallFunc. Возможно у меня старая версия гиппомоков? Это устаревшая система, и в ней все старое. GCC версии 4.8.5 и версия Boost 1.59. У меня нет возможности измениться.

zephod 25.07.2024 17:20

Обновлено изданием для путешественников во времени. Кроме того: всякий раз, когда вы слышите «у нас нет возможности измениться», я думаю: «у вас нет роскоши оставаться позади». Это просто плохой менеджмент. Но мы все были там.

sehe 25.07.2024 20:11

Другие вопросы по теме