2017-07-25 4 views
2

J'écris des tests unitaires pour une classe C++ en utilisant GoogleTest et GoogleMock. Mon code actuel ressemble ci-dessous:GoogleMock: Comment valider les paramètres d'entrée avec le nombre d'invocations?

MockNetConnector* connector = new MockNetConnector(); 
NetClient* client = new NetClient(connector); 

TEST_F(NetClientTest, connect) 
{ 
    EXPECT_CALL(*connector, attempt_connect(_,_)).Times(3) 
     .WillOnce(Return(false)) 
     .WillOnce(Return(false)) 
     .WillOnce(Return(true)); 

    std::string srv_list = "127.0.0.1:30001,127.0.0.2:30002,127.0.0.3:30003"; 
    bool is_connected = client->connect(srv_list); 

    ASSERT_TRUE(is_connected); 
} 

Comme vous pouvez le voir, le (*connector).attempt_connect(_,_) actuellement ne valident pas les paramètres d'entrée. Maintenant, je veux qu'il valide l'entrée à chaque invocation, c'est-à-dire que l'entrée doit être (127.0.0 x, 3000 x) pour l'invocation x-.

Je sais comment valider des paramètres pour des valeurs fixes, par ex. attempt_connect(StrEq("127.0.0.1"),Eq(30001)), mais ne savent pas comment valider les paramètres qui varient d'invocation à invocation.

Répondre

0

J'ai trouvé une solution à la question, mais peut-être pas le meilleur.

Tout d'abord, définir une variable globale appelée postfix:

static int postfix = 0; 

Ecrivez des matchers:

MATCHER(ValidateIP, "") 
{ 
    std::string expected_ip = "127.0.0." + to_string(::ip_postfix); 

    return (expected_ip == arg); 
} 

MATCHER(ValidatePort, "") 
{ 
    int expected_port = 30000 + ::port_postfix; 

    return (expected_port == arg); 
} 

Ecrire une coutume action qui augmente postfix après chaque appel.

ACTION(IncreasePostfix) 
{ 
    ::postfix++; 
} 

Appliquer les matchers à l'attente:

EXPECT_CALL(*connector, attempt_connect(ValidateIP(),ValidatePort())).Times(3) 
    .WillOnce(DoAll(IncreasePostfix(), Return(false))) 
    .WillOnce(DoAll(IncreasePostfix(), Return(false))) 
    .WillOnce(DoAll(IncreasePostfix(), Return(true))); 

Pour rendre le postfix a un effet individuellement à chaque test, les remettre à zéro juste avant le début du test (à savoir l'intérieur NetClientTest::SetUp())

class NetClientTest : public testing::Test 
{ 
    virtual void SetUp() { 
     ::postfix = 1; 
    } 

    // other methods 
};