То, что вы описываете, является совершенно нормальной ситуацией, и существуют установленные шаблоны, которые могут помочь вам реализовать ваши тесты таким образом, чтобы это не повлияло на ваш производственный код.
Одним из способов решения этой проблемы является использование Специфичного для теста подкласса , где вы можете добавить установщик для элемента сокета и использовать фиктивный сокет в случае теста. Конечно, вам нужно сделать переменную защищенной, а не частной, но это, вероятно, не так уж важно. Например:
class RPCClientProxy
{
...
protected:
Socket* pSocket;
...
};
class TestableClientProxy : public RPCClientProxy
{
TestableClientProxy(Socket *pSocket)
{
this->pSocket = pSocket;
}
};
void SomeTest()
{
MockSocket *pMockSocket = new MockSocket(); // or however you do this in your world.
TestableClientProxy proxy(pMockSocket);
....
assert pMockSocket->foo;
}
В конце концов, все сводится к тому, что вам часто (чаще, чем не в C ++) приходится разрабатывать свой код таким образом, чтобы сделать его тестируемым, и в этом нет ничего плохого. Если вы можете избежать утечки этих решений в общедоступные интерфейсы, что иногда может быть лучше, но в других случаях может быть лучше выбрать, например, внедрение зависимостей через параметры конструктора, скажем, с использованием синглтона для предоставления доступа к конкретному экземпляру. .
Примечание: вероятно, стоит заглянуть на остальную часть сайта xunitpatterns.com : здесь есть масса хорошо отработанных шаблонов юнит-тестирования, которые можно понять, и мы надеемся, что вы сможете получить их из тех, кто был там до тебя :)