Подтвердить что ты не робот

Может ли Google выманить метод с типом возвращаемого интеллектуального указателя?

У меня есть factory, который возвращает умный указатель. Независимо от того, какой умный указатель я использую, я не могу заставить Google Mock издеваться над методом factory.

Макет-объект представляет собой реализацию чистого абстрактного интерфейса, где все методы являются виртуальными. У меня есть прототип:

MOCK_METHOD0(Create, std::unique_ptr<IMyObjectThing>());

И я получаю:

"...gmock/gmock-spec-builders.h(1314): error C2248: 'std::unique_ptr<_Ty>::unique_ptr' : cannot access private member declared in class 'std::unique_ptr<_Ty>'"

Определен тип, указанный в интеллектуальном указателе.

И я пытаюсь получить доступ к одному из конструкторов, объявленному частным, но я не понимаю, почему. Когда это было std:: auto_ptr, ошибка указала, что не существует конструктора копирования, что меня смущает.

Во всяком случае, есть способ для Mock метода, который возвращает умный указатель? Или есть лучший способ создать factory? Единственное мое решение - вернуть необработанный указатель (blech...)?

Моя среда - это Visual Studio 2010 Ultimate и Windows 7. Я не использую CLI.

4b9b3361

Ответ 1

Google Mock требует, чтобы в большинстве случаев параметры и возвращаемые значения отталкиваемых методов были скопируемыми. Per повысить документацию, unique_ptr не копируется. У вас есть возможность вернуть один из классов интеллектуального указателя, который использует совместное владение (shared_ptr, linked_ptr и т.д.) И, таким образом, можно копировать, Или вы можете использовать необработанный указатель. Поскольку рассматриваемый метод, по-видимому, является методом построения объекта, я не вижу неотъемлемой проблемы с возвратом необработанного указателя. Пока вы назначаете результат на какой-либо общий указатель на каждом сайте, вы будете в порядке.

Ответ 2

Возможное обходное решение для проблем с фреймворком google с аргументами функции копирования (const) и значения retun - это использовать методы прокси-макета.

Предположим, что у вас есть следующее определение интерфейса (если это хороший стиль для использования std::unique_ptr таким образом, кажется, более или менее философский вопрос, мне лично нравится, чтобы обеспечить передачу права собственности):

class IFooInterface {
public:
    virtual void nonCopyableParam(std::unique_ptr<IMyObjectThing> uPtr) = 0;
    virtual std::unique_ptr<IMyObjectThing> nonCopyableReturn() = 0;
    virtual ~IFooInterface() {}
};

Соответствующий класс mock может быть определен следующим образом:

class FooInterfaceMock
: public IFooInterface {
public:
    FooInterfaceMock() {}
    virtual ~FooInterfaceMock() {}

    virtual void nonCopyableParam(std::unique_ptr<IMyObjectThing> uPtr) {
        nonCopyableParamProxy(uPtr.get());
    }
    virtual std::unique_ptr<IMyObjectThing> nonCopyableReturn() {
        return std::unique_ptr<IMyObjectThing>(nonCopyableReturnProxy());
    }


    MOCK_METHOD1(nonCopyableParamProxy,void (IMyObjectThing*));
    MOCK_METHOD0(nonCopyableReturnProxy,IMyObjectThing* ());
};

Вам просто нужно позаботиться о том, чтобы конфигурации (предпринятые действия) для метода nonCopyableReturnProxy() возвращали либо NULL, либо экземпляр, распределенный динамически в куче.


Там google-mock user forum thread обсуждает эту тему, где один из сопровождающих утверждает, что фреймворк google-mock не будет изменен для поддержки этого в будущем утверждая, что их политика сильно препятствует использованию параметров std::auto_ptr. Как уже упоминалось, это IMHO - философская точка зрения, и возможности издевательской структуры не должны управлять теми интерфейсами, которые вы хотите спроектировать, или вы можете использовать их от сторонних API.

Как сказано, ответ описывает способ выполнимый.

Ответ 3

Я знаю, что этот пост был сделан очень давно, поэтому вы, вероятно, уже нашли ответ.

Ранее gmock не поддерживал фиктивные функции, которые возвращали любой подвижный тип, включая умные указатели. Однако в апреле 2017 года компания gmock представила новый модификатор Action ByMove.

EXPECT_CALL(*foo_, Bar(_, )).WillOnce(Return(ByMove(some_move_only_object)));

где some_move_only_object может быть, например, std::unique_ptr.

Так что да, теперь gmock может смоделировать функцию, которая принимает умный указатель.

Ответ 4

Недавно я обнаружил, что возвращение умных указателей с помощью имитированных функций все еще не очень удобно для пользователя. Да, новое действие ByMove было введено, однако оказывается, что его можно использовать только один раз во время теста. Итак, представьте, что у вас есть фабричный класс для тестирования, который многократно возвращает unique_ptr вновь созданному объекту.

Любая попытка .WillRepeatedly(Return(ByMove) или нескольких ON_CALL с .WillByDefault(Return(ByMove) приведет к следующей ошибке:

[FATAL] Условие! Выполнено_ не выполнено. Действие ByMove() должно быть выполнено только один раз.

Это также четко указано в GMock Cookbook в параграфе "Методы насмешки, использующие типы только для перемещения".

Ответ 5

Я знаю, что этот пост был сделан очень давно, поэтому вы, вероятно, уже нашли ответ.

В апреле 2017 года компания gmock представила новый модификатор действия "ByMove".

EXPECT_CALL (* foo_, Bar (_,)). WillOnce (Return (ByMove (some_move_only_object))));

Ответ 6

в фиктивном классе ставь так же как хочешь

MOCK_METHOD0 (Создать, std::unique_ptr());


и в тесте, как показано ниже

EXPECT_CALL(<mock-obj>, Create())
.WillOnce([]()->std::unique_ptr<IMyObjectThing>{
    return std::make_unique<IMyObjectThing>();
});

если версия 2010 не поддерживает лямбду, вы можете использовать функтор