Как создать внедрение зависимости для тестирования QTcpSocket?

Я пытаюсь написать модульные тесты для приложения Qt5, которое я написал, но я озадачен тем, как обращаться с классами, которые включают в себя работу в сети. Мой основной класс включает в себя подкласс QTcpServer, который переопределяет QTcpServer ::comingConnection для создания объекта ClientConnection и передает его потоку:

void NetworkServer::incomingConnection(qintptr socketDescriptor)
{
QThread* clientThread = new QThread();
ClientConnection* clientConnection = new ClientConnection(socketDescriptor);
clientConnection->moveToThread(clientThread);

// connect signals & slots to ClientConnection (removed for clarity)

connect(clientThread, &QThread::started, clientConnection, &ClientConnection::run);
clientThread->start();
}

Класс ClientConnection использует socketDescriptor для открытия нового QTcpSocket в выделенном потоке, получения данных от клиента и их обработки.

ClientConnection::ClientConnection(int socketDescriptor, QObject *parent) :
QObject(parent), socketDescriptor(socketDescriptor)
{
tcpIncomingData = new QByteArray;
}

void ClientConnection::run()
{
QTcpSocket socket;
if(!socket.setSocketDescriptor(socketDescriptor)) {
emit sig_error(socket.error());
return;
}

if(socket.waitForReadyRead(5000)) {
*tcpIncomingData = socket.readAll();
qDebug() << "data received: " << tcpIncomingData;
} else {
qDebug() << "socket timed out!";
}

parseXmlData();

socket.disconnectFromHost();
socket.waitForDisconnected();
}

Этот класс не закончен, но я хочу начать писать тесты сейчас. Моя проблема заключается в том, как обрабатывать socketDescriptor. Я предполагаю, что мне нужно использовать какое-то внедрение зависимостей, но я не думаю, что это осуществимо без создания всего QTcpServer в тестовом примере.

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

3

Решение

Прежде всего, вы можете определить чистые интерфейсы (т.е. чисто абстрактные классы) для ваших занятий, так что насмешка и обмен ими не будет проблемой, скажем, IClientConnection,

Затем вы можете объявить свои зависимости явно, то есть либо передать IClientConnection фабрика или экземпляр IClientConnection к NetworkServer конструктор.

В вашем тесте теперь вы можете реализовать макет IClientConnection и передать его или его фабрику (также может быть интерфейсом) конструктору в тесте. Возможно, вы захотите использовать умный указатель (shared_ptr или что-то родное для Qt), так что автоматическое освобождение ресурсов минимизирует ошибки.

Если ваше программное обеспечение растет, и вы пишете много ручного внедрения зависимостей, вы можете использовать библиотеку DI. Я недавно начал обзор некоторых из доступных библиотек C ++ DI.

Наконец, вы можете далеко уйти, посмеявшись над своими зависимостями, используя фальшивую среду, такую ​​как googlemock.

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]