Можно ли издеваться над возвращаемым значением вызываемой функции, используя gtest или gmock?

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

#include <stdio.h>
#include "gtest/gtest.h"

int ret()
{
    return 5;
}

class A
{
    public:
        A();
        int a;
        int func();
};

A::A()
{
    printf("This is constructor\n");
}

int A::func()
{
    int iRet = ret(); /* When func() is called by gtest I would like to control the return value of ret() */
    int iRet1 = ret();
    /* Based on these two values some operations to be done */
    printf("This is func. %d, %d\n", iRet, iRet1);
    return iRet;
}

TEST (abc, xyz) {
    A a;
    EXPECT_EQ(5, a.func()); /* Here how to get different values of iRet and iRet1 for ret() function? */
}

int main(int argc, char **argv)
{
    ::testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}

В случае, если это невозможно через gtest и/или gmock, пожалуйста, предложите мне любой другой инструмент для того же.

Также я пробовал со следующей вещью, которая не работает должным образом:

int ret()
{
    printf("Returning 5\n");
    return 5;
}

int ret1()
{
    int iRet = 10;
    printf("Inside ret1\n");
    iRet = ret();
    if (iRet == 5)
    {
        printf("Original ret is called\n");
    }
    else if (iRet == 100)
    {
        printf("This is mocked function call\n");
    }
    else
    {
        printf("Opps! This should not happen\n");
    }
    return iRet;
}

class FooMock {
    public:
        MOCK_METHOD0(ret, int());
        MOCK_METHOD0(ret1, int());
};

TEST (abc, xyz) {
    FooMock mock;
    EXPECT_CALL(mock, ret()).Times(1).WillOnce(Return(100));
    mock.ret1();
}
int main(int argc, char **argv)
{
    ::testing::InitGoogleMock(&argc, argv);
    return RUN_ALL_TESTS();
}

Во время работы выдает следующую ошибку:

$ ./a.out 
[==========] Running 1 test from 1 test case.
[----------] Global test environment set-up.
[----------] 1 test from abc
[ RUN      ] abc.xyz
gtest.cpp:86: Failure
Actual function call count doesn't match EXPECT_CALL(mock, ret())...
         Expected: to be called once
           Actual: never called - unsatisfied and active
gtest.cpp:87: Failure
Actual function call count doesn't match EXPECT_CALL(mock, ret())...
         Expected: to be called once
           Actual: never called - unsatisfied and active
[  FAILED  ] abc.xyz (0 ms)
[----------] 1 test from abc (0 ms total)

[----------] Global test environment tear-down
[==========] 1 test from 1 test case ran. (0 ms total)
[  PASSED  ] 0 tests.
[  FAILED  ] 1 test, listed below:
[  FAILED  ] abc.xyz

 1 FAILED TEST

Пожалуйста, дайте мне знать, если я что-то делаю не так...


person Dipankar Saha    schedule 30.05.2017    source источник
comment
См. документацию по концепциям модульного тестирования: stackoverflow.com/documentation/unit-testing/topics Идея заключается в том, что вы вызываете свой метод с примерными данными и сравниваете результат с тем, что, как вы знаете, является правильным результатом. Сначала я бы не стал заморачиваться с покрытием кода, начал бы писать хорошие тесты.   -  person Gerriet    schedule 30.05.2017


Ответы (2)


Итак, идея модульного тестирования заключается в том, что вы запускаете часть своего кода и сравниваете результаты с тем, что вы ожидаете получить. Ваш код делает его более сложным, чем он должен быть. Например.

#include <stdio.h>
#include "gtest/gtest.h"

int incBy5(const int a) {
  return a+5;
}

TEST (abc, xyz) {
  int x=17;
  EXPECT_EQ(x+5, incBy5(x));
}

int main(int argc, char **argv)
{
  ::testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}

См. документацию по концепциям модульного тестирования в целом и google-test в частности. Насмешливый аспект всего этого проявляется в более сложных вещах для тестирования, когда у вас может не быть всего доступного (например, сетевые ресурсы, базы данных, ...), и вы создаете макеты, которые могут заменить эти ресурсы.

person Gerriet    schedule 30.05.2017

Во втором фрагменте вы определяете два фиктивных метода, ret и ret1. Позже вы устанавливаете ожидание ret, но вызываете ret1. В конце теста ожидание ret остается невыполненным, что вызывает жалобу gmock.

person VladLosev    schedule 31.05.2017
comment
Спасибо за ваш ответ. Я ожидаю, когда ret1 вызывается, пытаясь контролировать возвращаемое значение ret (ret вызывается ret1). Есть идеи? - person Dipankar Saha; 31.05.2017
comment
Обратите внимание, что gmock не поддерживает прямое издевательство над бесплатными функциями. Он издевается только над методами класса, виртуальными. Я предлагаю прочитать руководство gmock по адресу github.com/google/googletest/blob/master/googlemock/docs/, чтобы лучше понять, как это работает и как его использовать. TL;DR: создайте методы ret и ret1 и смоделируйте ret. - person VladLosev; 02.06.2017