web-dev-qa-db-fra.com

Comment spécifier des retours consécutifs dans gmock?

Dans Mockito, nous pouvons spécifier plusieurs retours comme (pris de ici ):

//you can set different behavior for consecutive method calls.
 //Last stubbing (e.g: thenReturn("foo")) determines the behavior of further consecutive calls.
 when(mock.someMethod("some arg"))
  .thenReturn(new RuntimeException())
  .thenReturn("foo");

 //There is a shorter way of consecutive stubbing:
 when(mock.someMethod()).thenReturn(1,2,3);
 when(mock.otherMethod()).thenThrow(exc1, exc2);

Existe-t-il un moyen de spécifier plusieurs retours pour une maquette réalisée avec gmock? Actuellement j'ai:

store_mock_ = std::make_shared<StorageMock>();
ON_CALL(*store_mock_, getFileName(_)).Return("file1").Return("file2");

qui ne compile pas parce que je ne peux pas comprendre les rendements multiples dans gmock. Est-ce possible avec gmock? Si non, existe-t-il un autre moyen de résoudre ce problème? J'ai constaté que nous pouvons EXPECT plusieurs valeurs de retour telles que:

using ::testing::Return;...
EXPECT_CALL(turtle, GetX())
    .WillOnce(Return(100))
    .WillOnce(Return(200))
    .WillOnce(Return(300));

Cependant, je n'ai trouvé aucun document permettant de se moquer de plusieurs déclarations avec ON_CALL.

13

ON_CALL est plus utilisé pour définir le comportement par défaut de la fonction. C'est à dire. vous savez que dans le code testé, la fonction simulée est appelée, vous souhaitez définir une valeur par défaut, mais le nombre de fois où la fonction est appelée n'a pas vraiment d'importance.

Le exemple :

  ON_CALL(foo, Sign(_))
      .WillByDefault(Return(-1));
  ON_CALL(foo, Sign(0))
      .WillByDefault(Return(0));
  ON_CALL(foo, Sign(Gt(0)))
      .WillByDefault(Return(1));

Pour obtenir le comportement souhaité, je voudrais utiliser attentes - vous avez déjà fourni un exemple en question, pour en montrer plus - un exemple dans lequel vous attendez 1, 2 puis toujours 3:

  EXPECT_CALL(foo, Sign(_))
      .WillOnce(Return(1))
      .WillOnce(Return(2))
      .WillRepeatedly(Return(3));

EXPECT_CALL "way" peut être gênant lorsque vous souhaitez définir ceci dans le dispositif de test SetUp - et certains tests peuvent appeler foo une seule fois. Mais, bien sûr, il existe des moyens de "contrôler" la valeur de renvoi ON_CALL pour les appels suivants - mais vous devez le faire avec des actions spéciales - comme obtenir le résultat d'une fonction - comme dans cet exemple:

class IDummy
{
public:
    virtual int foo() = 0;
};

class DummyMock : public IDummy
{
public:
    MOCK_METHOD0(foo, int());
};
using namespace ::testing;
class DummyTestSuite : public Test
{
protected:
    DummyMock dummy;
    void SetUp() override
    {
        ON_CALL(dummy, foo())
           .WillByDefault(
                 InvokeWithoutArgs(this, &DummyTestSuite::IncrementDummy));
    }
    int dummyValue = 0;
    int IncrementDummy()
    {
        return ++dummyValue;
    }

};


TEST_F(DummyTestSuite, aaa)
{
    ASSERT_EQ(1, dummy.foo());
    ASSERT_EQ(2, dummy.foo());
    ASSERT_EQ(3, dummy.foo());

} 
15
PiotrNycz

La réponse de @ PiotrNycz est correcte et constitue la solution privilégiée.

Une approche alternative via une fonction lambda peut vous donne plus de flexibilité:

uint32_t callCount = 0;
ON_CALL(*turtle, GetX())
    .WillByDefault(testing::Invoke(
        [&callCount]() -> int {
            return ++callCount * 100;
        }
    ));
0
Roland Ettinger