web-dev-qa-db-fra.com

gmock définissant les actions par défaut / ON_CALL vs EXPECT_CALL

Je ne comprends pas la différence entre ON_CALL et EXPECT_CALL lors de son utilisation pour spécifier l'action par défaut.

Jusqu'à présent, j'ai remarqué/appris qu'il y a deux façons d'ajuster l'action par défaut d'une maquette:

ON_CALL(mock, methodX(_)).WillByDefault(Return(0x01));

ou

EXPECT_CALL(mock, methodX(_)).WillRepeatedly(Return(0x01));

Quelqu'un pourrait-il m'expliquer:

  • La différence entre les deux méthodes
  • Les hauts et les bas de chacun
  • Quand est-il approprié de les utiliser (quel type de configuration ...)
44
Nicoretti

Il existe des différences subtiles mais significatives entre les deux déclarations. EXPECT_CALL Définit l'attente d'un faux appel. L'écriture

EXPECT_CALL(mock, methodX(_)).WillRepeatedly(do_action);

indique à gMock que methodX peut être appelé mock autant de fois avec n'importe quel argument, et quand c'est le cas, mock exécutera do_action. D'autre part,

ON_CALL(mock, methodX(_)).WillByDefault(do_action);

indique à gMock que chaque fois que methodX est invoqué sur mock, il doit exécuter do_action. Cette fonctionnalité est utile dans un scénario où vous devez écrire de nombreuses attentes sur votre maquette, et la plupart/toutes doivent spécifier la même action - surtout si c'est complexe. Vous pouvez spécifier cette action dans ON_CALL, Puis écrire EXPECT_CALL Sans spécifier explicitement l'action. Par exemple.,

ON_CALL(mock, Sign(Eq(0), _))
  .WillByDefault(DoAll(SetArgPointee<1>("argument is zero"), Return(0)));
ON_CALL(mock, Sign(Gt(0), _))
  .WillByDefault(DoAll(SetArgPointee<1>("argument is positive"), Return(1)));
ON_CALL(mock, Sign(Lt(0), _))
  .WillByDefault(DoAll(SetArgPointee<1>("argument is negative"), Return(-1)));

Maintenant, si vous devez écrire beaucoup de EXPECT_CALL, Vous n'avez pas besoin de mock de spécifier le comportement à chaque fois:

EXPECT_CALL(mock, Sign(-4, _));
EXPECT_CALL(mock, Sign(0, _));
EXPECT_CALL(mock, Sign(1, _)).Times(2);
EXPECT_CALL(mock, Sign(2, _));
EXPECT_CALL(mock, Sign(3, _));
EXPECT_CALL(mock, Sign(5, _));

Dans un autre exemple, en supposant que Sign renvoie int, si vous écrivez

ON_CALL(mock, Sign(Gt(0), _)).WillByDefault(Return(1));
EXPECT_CALL(mock, Sign(10, _));

l'appel mock.Sign(10) renverra 1 car ON_CALL fournit le comportement par défaut pour un appel spécifié par EXPECT_CALL. Mais si vous écrivez

EXPECT_CALL(mock, Sign(Gt(0), _).WillRepeatedly(Return(1));
EXPECT_CALL(mock, Sign(10, _));

l'invocation de mock.Sign(10, p) renverra 0. Elle sera comparée à la seconde attente. Cette attente ne spécifie aucune action explicite et gMock générera une action par défaut pour cela. Cette action par défaut consiste à renvoyer une valeur par défaut du type de retour, qui est 0 pour int. La première attente sera totalement ignorée dans ce cas.

47
VladLosev
ON_CALL(mock, methodX(_)).WillByDefault(Return(0x01));
EXPECT_CALL(mock, methodX(_)).WillRepeatedly(Return(0x01));

Comme vous l'avez dit, ces deux lignes font exactement la même chose, il n'y a donc aucune différence. Utilisez l'une ou l'autre façon pour définir une action par défaut à votre guise.

Cependant, il existe une différence logique:

  • ON_CALL(mock, methodX(_)).WillByDefault(Return(0x01)); signifie que la méthode peut être appelée, et si cela se produit, chaque appel renverra 0x01
  • EXPECT_CALL(mock, methodX(_)).WillRepeatedly(Return(0x01)); signifie que la méthode devrait être appelée et que chaque appel renverra 0x01

Soit dit en passant, il y a Définition des actions par défaut dans leur aide-mémoire, qui dit:

Pour personnaliser l'action par défaut pour une méthode particulière, utilisez ON_CALL ():

ON_CALL(mock_object, method(matchers))
    .With(multi_argument_matcher)  ?
    .WillByDefault(action);
10
BЈовић