2015-11-14 6 views
4

Я довольно новичок в том, чтобы использовать способ работы.Как вызвать метод на объекте, переданном издеваемому методу

У меня есть mock с методом addEvent, который принимает объект типа MyClass указателем. Мне нужно вызвать MyClass :: makeCall на этом объекте.

class SchedulerMock 
{ 
public: 
    MOCK_CONST_METHOD1(addEvent, void(MyClass*)); 

}; 

Я нашел эту тему: What is the easiest way to invoke a member function on an argument passed to a mocked function?

И там пример:

IFooable* ifooable = new IFooableImpl(...); 
TMockFoo MockFoo; 
ON_CALL(MockFoo, Foo(_)) 
    .WithArg<0>(Invoke(&ifooable,&IFooable::Fooable)); 

Но я не хочу вызвать метод для объекта я создал в тесте. Я хочу, чтобы mock вызывал makeCall на объекте, который фактически передается макету. Итак, я могу приложить свой макет к другому классу, который создаст несколько новых объектов, и вызовет addEvent в моем schedulerMock, и я бы хотел, чтобы этот макет вызывал makeCall по переданному аргументу каждый раз, когда кто-то вызывает addEvent на мой макет. Надеюсь, я поняла.

Это можно сделать?

+0

я принял удар на моем понимании того, что вы хотите сделать ... Пожалуйста, дайте мне знать, с помощью небольшого примера, если я неправильно вы. –

ответ

1

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

class SchedulerMock 
{ 
    public: 
    //.... etc 
    void addEvent(MyClass* c) const 
    { 
     c->makeCall(); 
     mockAddEvent(c); //Wholla, test still works and makeCall called. 
    } 

    MOCK_CONST_METHOD1(mockAddEvent, void(MyClass*)); 
}; 
+0

Хм это интересно. У меня на самом деле была другая идея. Как добавить функцию для издевательства. void makeCall (MyClass * p) {p-> makeCall();} , а затем в ожидании сделать что-то вроде этого: EXPECT_CALL (scheduler, addEvent (_)). WillOnce (Invoke (& scheduler, & SchedulerMock :: makeCall)) ; Я попробую вас тоже подойти. Спасибо за этот намек :) –

+0

Это просто и работает. Я часто использую шаблон для возврата объектов с семантикой перемещения (например, unique_pointer). Обычно я делал бы addEvent частным, но у вас нет интерфейса с общедоступным addEvent (в общем-то, хорошая идея получить из интерфейса для насмешек/stubbing целей, пока вы не знаете, что скорость является проблемой). –

+0

Да, обычно я фыркнул бы на интерфейс, но здесь я пытаюсь издеваться над синглоном, поэтому мой SchedulerMock не получается из реального объекта, он просто имеет методы с одинаковыми сигнатурами. Затем мне нужно сориентировать классы, которые используют этот планировщик. Я использую так называемый hi-perf, издевательский из google coobook: http://code.google.com/p/googlemock/wiki/CookBook#Mocking_Nonvirtual_Methods Дело в том, что я не могу наследовать событие из этого синглтона, потому что в его конструкторе он вызывает другой синглтон. –

1

Вы можете определить пользовательские действия (в области видимости пространства имен - вне любых других функций, тестов и т.д.). Действие будет иметь доступ к аргументам вызова издевались функции, которая в данном случае является MyClass * вы хотите позвонить makeCall на:

ACTION(MakeCall) 
{ 
    // arg0 is predefined as 0-th argument passed to the mock function call, 
    // MyClass* in this case 
    arg0->makeCall(); 
} 

TEST(...) 
{ 
    // Create mock object and set expectation, and specify to invoke the 
    // MakeCall Action 
    SchedulerMock mock; 
    EXPECT_CALL(mock, addEvent(_)) 
     .WillOnce(MakeCall()); 

    ... 
} 

Когда mock.addEvent(my_class_ptr) вызвана, MakeCall действия будет вызываться с заданной MyClass * указатель.

Вы также можете использовать это, чтобы передать параметры, определенные в тесте, в действие. Например, если ваш метод MyClass::makeCall взял int параметр, скажем, и вы хотели передать два различных значения первой и второй раз метод называется:

class MyClass 
{ 
    void makeCall(int); 
}; 

ACTION_P(MakeCall, value) 
{ 
    arg0->makeCall(value); 
} 

TEST(...) 
{ 
    const int FIRST_VAL = 10; 
    const int SECOND_VAL = 20; 

    MyClass my_class_obj; 
    SchedulerMock mock; 
    EXPECT_CALL(mock, addEvent(_)) 
     .WillOnce(MakeCall(FIRST_VAL)) 
     .WillOnce(MakeCall(SECOND_VAL)); 
    ... 
} 

См фиктивный документации Google для получения более подробной информации:

Google Mock Cheat Sheet - Defining Actions

Google Mock Cookbook - Writing New Actions Quickly

 Смежные вопросы

  • Нет связанных вопросов^_^