Подтвердить что ты не робот

Как сделать google-test классы друзьями с моими классами?

Я слышал, что есть возможность включить google-test TestCase для моих классов, что позволяет тестировать доступ к моим частным/защищенным членам.

Как это сделать?

4b9b3361

Ответ 1

Попробуйте (прямо из Google Test docs...):

FRIEND_TEST(TestCaseName, TestName);

Например:

// foo.h
#include <gtest/gtest_prod.h>

// Defines FRIEND_TEST.
class Foo {
  ...
 private:
  FRIEND_TEST(FooTest, BarReturnsZeroOnNull);
  int Bar(void* x);
};

// foo_test.cc
...
TEST(FooTest, BarReturnsZeroOnNull) {
  Foo foo;
  EXPECT_EQ(0, foo.Bar(NULL));
  // Uses Foo private member Bar().
}

Ответ 2

Я знаю, что это старо, но я искал тот же ответ сегодня. "gtest_prod.h" просто вводит простой макрос для сравнения тестовых классов.

#define FRIEND_TEST(test_case_name, test_name)\
friend class test_case_name##_##test_name##_Test

So FRIEND_TEST(FooTest, BarReturnsZeroOnNull); эквивалентно:

friend class FooTest_BarReturnsZeroOnNull_Test;

Это работает, потому что каждый тест является его собственным классом, как указано в предыдущем ответе.

Ответ 3

Стратегия гораздо лучше - не допускать тесты друзей среди ваших модульных тестов.

Предоставление другим тестам доступа к закрытым членам приведет к созданию базы кода, которую трудно поддерживать. Тестирование, которое прерывается всякий раз, когда детали внутренней реализации компонента реорганизуются, не то, что вы хотите. Если приложить дополнительные усилия для получения дизайна, где компоненты могут быть протестированы через их открытый интерфейс, вы получите тесты, которые необходимо обновлять только при обновлении открытого интерфейса компонента.

Испытания, основанные на gtest/gtest_prod.h, следует рассматривать как признак плохой конструкции.

Ответ 4

Когда ваш тестируемый класс и ваш тестовый класс находятся в другом пространстве имен (например, ваши тесты находятся в глобальном пространстве имен), вам может потребоваться предварительно объявить тестовый класс и добавить префикс пространства имен в FRIEND_TEST:

// foo.h
#include <gtest/gtest_prod.h>

class FooTest_BarReturnsZeroOnNull_Test;

// Defines FRIEND_TEST.
class my_namespace::Foo {
  ...
 private:
  FRIEND_TEST(::FooTest, BarReturnsZeroOnNull);
  int Bar(void* x);
};

// foo_test.cc
using namespace my_namespace;

...
TEST(FooTest, BarReturnsZeroOnNull) {
  Foo foo;
  EXPECT_EQ(0, foo.Bar(NULL));
  // Uses Foo private member Bar().
}

Я знаю, что юнит-тесты друзей (или дружелюбие в C++ в целом) и тестирование белого ящика являются спорным предметом, но когда вы работаете над сложными научными алгоритмами, каждый шаг которых вы должны тестировать и проверять, но это Если вы не хотите показывать в общедоступных (или даже защищенных) интерфейсах, тесты для друзей кажутся мне простым и прагматичным решением, особенно в подходе к разработке на основе тестов. Всегда возможно провести рефакторинг кода позже (или полностью удалить тесты белого ящика), если он использует одну религию для проверки удобства или белого ящика.