#c #unit-testing #boost #turtle-mock
#c #модульное тестирование #boost #черепаха-макет
Вопрос:
Я долгое время скрываюсь на доске, и нет необходимости говорить, что вы, ребята, лучшие, и я благодарен за все время, когда вы спасали мою работу. Это мой первый пост здесь, и я надеюсь, что я ничего не напутал.
Я пишу приложение C Boost для Linux (виртуализированный Ubuntu 16.04 amd_64) и использую Turtle Mock для mocking framework и Boost Test для платформы тестирования. Когда я пытаюсь протестировать класс, который использует метод внедрения зависимостей, я имитирую классы, которые необходимо передать тестируемому классу, чтобы я мог проверить последовательность их вызова. Пока все хорошо, но проблема возникает здесь. Я использую MOCK_BASE_CLASS(MockAClass, AClass), чтобы переопределить виртуальные методы реального класса AClass и использовать новый MockAClass для продолжения моих тестов. Допустим, у AClass есть виртуальный метод int getTest(int), а у MockAClass есть MOCK_METHOD(getTest, 1, int(int)), после установки ожидаемого значения и возвращаемого значения для метода getTest объекта MockAClass и вызова метода, ожидаемое значение которого в большинстве случаев равно MOCK_EXPECT(objMockAClass.getTest).at_least(1) НИКОГДА не проверяется. Я могу контролировать возвращаемое значение, но вызов никогда не проверяется, как это произошло. Это происходит только в том случае, если функция возвращает значение (например, если функция имеет значение void getTest(int), тогда проверка пройдет).
Я прилагаю простой PoC моей проблемы, которая завершится сбоем в моей системе.
class AClass
{
public:
virtual int getTest(int a) {return 0}
}
MOCK_BASE_CLASS (MockAClass, AClass)
{
MOCK_METHOD(getTest, 1, int(int));
}
BOOST_AUTО_TEST_CASE(SomeClassFunctionality)
{
MockAClass objMockAClass;
MOCK_EXPECT(objMockAClass.getTest).returns(1);
MOCK_EXPECT(objMockAClass.getTest).at_least(1);
objMockAClass.getTest(1);
}
Ответ №1:
MOCK_EXPECT(objMockAClass.getTest).returns(1);
MOCK_EXPECT(objMockAClass.getTest).at_least(1);
На самом деле это два ожидания. Первый означает «каждый раз, когда вызывается getTest, возвращается 1», а второй «getTest должен вызываться хотя бы один раз».
Проблема в том, что первый всегда будет совпадать, поэтому у второго не будет шансов быть запущенным.
Комментарии:
1. Да, это правильно. Он обрабатывает их как два отдельных взаимоисключающих оператора, и именно поэтому он завершается с ошибкой. Спасибо за поддержку. 🙂
Ответ №2:
Проблема решается, если отдельные операторы EXPECT объединяются в один полный оператор EXPECT .
MOCK_EXPECT(objMockAClass.getTest).at_least(1).returns(1);
— Это заставит пример работать так, как планировалось.
С уважением,