Создание тестов gmock для методов специализации шаблона

Я хочу добавить тесты GMOCK, чтобы проверить, обращается ли контейнер к правильному методу. Для vector он должен получить доступ ко второму методу, а для set он должен получить доступ к первому методу (поскольку set имеет set.find). Это моя специализация шаблона:

namespace tools{

struct low_priority {};
struct high_priority : low_priority {};

template<class TSource, class Ty>
auto exists_in(high_priority, const TSource &source, const Ty &item)
-> decltype(source->find(item) != source.end())
{
    return source.find(item) != source.end();
}

template<class TSource, class Ty>
auto exists_in(low_priority, const TSource &source, const Ty &item)
{
    return std::find(source.begin(), source.end(), item) != source.end();
}


template<class TSource, class Ty>
auto exists_in(const TSource &source, const Ty &item)
{
    return exists_in(high_priority{}, source, item);
}
}

person danielgabor    schedule 13.01.2021    source источник


Ответы (2)


Вы не можете использовать mock из бесплатных функций или методов шаблона.

Что вы можете сделать в этом случае, так это создать пользовательскую структуру и проверить, вызывается ли operator< (для std::set::find) или operator== (для std::find).

В качестве альтернативы вы можете создать фиктивный тип для std::set и проверить, вызывается ли метод find.

person Jarod42    schedule 13.01.2021
comment
я добавил выше альтернативный способ. - person danielgabor; 13.01.2021
comment
Как должен работать этот оператор ==? - person danielgabor; 14.01.2021
comment
std::set<MyType>::find использует MyType::operator<, тогда как std::find будет использовать MyType::operator== - person Jarod42; 14.01.2021
comment
Можете ли вы быть немного более ясным? - person danielgabor; 14.01.2021
comment
Обратите внимание на Demo с настраиваемым типом для инструментов (вместо этого можно смоделировать) некоторых операторов (< и ==). Вы можете увидеть используемый оператор в зависимости от используемого метода поиска. - person Jarod42; 14.01.2021
comment
Да, я не могу так, мне нужны тесты gmock .. - person danielgabor; 14.01.2021
comment
Используйте mock для MyType вместо печати, ожидайте 0 вызовов ==, когда следует использовать std::set::find. - person Jarod42; 14.01.2021

Я сделал это альтернативным способом для вектора, но он не работает, как правильно проверить, вызывается ли этот метод?

struct Interface
{
    virtual ~Interface() = default;
    virtual bool exists_in(std::vector<int>, int) = 0;
};

struct Implementation : Interface
{
    bool exists_in(std::vector<int> v, int i) override { tools::exists_in(v, i); }
};

class MockClass : public Interface {
public:
    MOCK_METHOD(bool, exists_in, (std::vector<int>, int));
};

**ADDED NEW**
TYPED_TEST_SUITE_P(ExistsInTestMethod);

TYPED_TEST_P(ExistsInTestMethod, ExistsInMethod)
{
    TypeParam Container = InitVectorContainer<TypeParam>();

    MockClass mock;
    EXPECT_CALL(mock, exists_in(Container, 5));
}
person danielgabor    schedule 13.01.2021
comment
@ Jarod42 это альтернативный способ - person danielgabor; 13.01.2021
comment
Я больше думаю о struct Mock {MOCK_METHOD(iterator, find, (int));MOCK_METHOD(iterator, end, ());};. - person Jarod42; 13.01.2021
comment
итератор? какой итератор? а зачем находить и заканчивать? - person danielgabor; 13.01.2021
comment
Я имел в виду создать поддельный std::set и проверить, что myset.find вызывается. - person Jarod42; 13.01.2021
comment
я добавил выше, как я EXPECT_CALL, как я должен знать, какой метод вызывается? - person danielgabor; 13.01.2021
comment
Как мне проверить? в ожидаемом вызове? используя все еще фиктивный класс - person danielgabor; 13.01.2021