Использование класса Friend Class против добавления аксессуров для модульного тестирования в C ++?

StackOverflow https://stackoverflow.com/questions/1149244

  •  18-09-2019
  •  | 
  •  

Вопрос

Лучше ли добавлять функции, которые возвращают внутреннее состояние объекта для модульного тестирования, в отличие от того, чтобы сделать класс тестирования другом? - Особенно, когда для функций нет никакого использования, за исключением случая модульного тестирования.

Это было полезно?

Решение

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

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

И, как вы справедливо сказали, загромождать общедоступную поверхность класса с неиспользованными вещами также нежелательно по своим причинам.

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

Другие советы

Я не согласен с принятым ответом и вместо этого рекомендую использовать класс Friend.

Часть состояния, которое вы тестируете, вероятно, специфична для реализации вашего класса; Вы тестируете детали, о которых обычно не знает или не заботится и не должен полагаться. Функции общественного доклада делают эти детали реализации частью интерфейса класса. Если внутреннее состояние, которое вы тестируете, не является частью предполагаемого интерфейса, оно не должно быть видно с помощью публичных функций. С пуриристической точки зрения вы застряли между двумя неправильными ответами, поскольку классы друзей также являются технически частью общественного интерфейса. На мой взгляд, возникает вопрос, какой вариант с меньшей вероятностью приведет к плохому выбору кодирования в будущем? Сопровождение с набором функций общедоступного доклада, зависящих от реализации, непреднамеренно поощряет зависимую от реализации концептуальную модель класса, что приведет к использованию класса в зависимости от реализации. Один класс друга, соответственно, назван и документирован, с меньшей вероятностью подвергается злоупотреблениям.

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

Использование классов друга для модульного тестирования является совершенно законным и позволяет вам поддерживать инкапсуляцию. Вы не должны изменять общественный интерфейс своих классов, чтобы сделать класс более тестируемым. Подумайте об этом таким образом. Что если вы приобрели стороннюю библиотеку FTP и пытаетесь ее использовать, и его публичный интерфейс загроможден кучей методов, о которых вам даже не нужно знать просто из -за модульных тестов! Даже изменение защищенного интерфейса для компенсации модульных тестов плохо. Если я унаследовал от какого -то класса, я не хочу беспокоиться о том, какие методы полезны для меня, а какие есть только из -за модульных тестов !!! Использование классов друзей для модульных тестов помогает вам поддерживать простой, легкий в использовании интерфейс класса; Это помогает сохранить инкапсуляцию и абстракцию !!!

Я слышал аргумент о том, что использование классов друзей для модульного тестирования является плохим, потому что тест на класс не должен «тесно связан» с его тестовым классом, и он не должен «знать» ничего о его тестовом классе. Я не покупаю это. Это одна строка, добавленная к вершине класса:

Друг класс MyClasstest;

А теперь вы можете протестировать свой класс любым способом!

Теперь я согласен с тем, что вы не должны использовать класс Friend, если это не необходимо. Если вы можете проверить, что нужно тестировать, не делая его другом, непременно. Но если жизнь становится сложной, и использование класса друга снова облегчает жизнь, используйте ее!

Я рекомендую использовать аксессов, а не разрешать доступ через общественных членов или классов друга.

Я не думаю, что использование класса Friend на самом деле дает вам какие -либо преимущества, и у него есть потенциал, чтобы сделать вашу жизнь намного хуже в будущем. Если ваш код будет оставаться рядом в течение долгого времени, есть большая вероятность, что его можно использовать так, как вы не ожидаете. Функции доступа могут использоваться только для тестирования сейчас, но кто знает, что произойдет в будущем? Использование аксессов, а не предоставление прямых доступа к переменным, дает вам гораздо большую гибкость, и он имеет очень низкую стоимость.

Другой аргумент заключается в том, что использование аксессов, а не общественных членов, является хорошей привычкой. Разработка хороших привычек является важным навыком в качестве программиста.

Как насчет того, чтобы сделать внутреннее состояние «защищенным»? А затем делайте, используя полученный класс.

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top