Примером этого исключаемого исключения является: Когда вы пытаетесь проверить что-то, это null.
Например:
string testString = null; //Because it doesn't have a value (i.e. it's null; "Length" cannot do what it needs to do)
if (testString.Length == 0) // Throws a nullreferenceexception
{
//Do something
}
Время выполнения .NET исключение NullReferenceException при попытке выполнить действие над чем-то, что не было инстанцировано, т.е. код выше.
По сравнению с ArgumentNullException, которое обычно выбрано как защитная мера, если метод ожидает, что то, что происходит
Дополнительная информация находится в C # NullReferenceException и Null Parameter .
Я бы сказал, нет.
@ Будем говорить, что вы должны стремиться к 100% охвату кода, но, на мой взгляд, это опасное отвлечение. Вы можете написать модульные тесты, которые имеют 100% -ный охват, и при этом абсолютно ничего не тестируют.
Для тестирования поведения вашего кода, выразительного и значимого, требуются модульные тесты, а getters / seters - это только означает конец. Если вы проверяете использование геттеров / сеттеров для достижения своей цели тестирования «реальной» функциональности, то это достаточно хорошо.
Если, с другой стороны, ваши геттеры и сеттеры делают больше, чем просто получают и устанавливают (т.е. они являются надлежащим образом сложными методами), то да, они должны быть протестированы. Но не пишите единичный тестовый пример только , чтобы проверить геттер или сеттеры, это пустая трата времени.
tl; dr: Да вы должны , а с OpenPojo тривиально.
setMom(Person p)
не должен позволять устанавливать кого-либо моложе себя, как свою мать. null
, у вас должен быть тест для этого, если кто-то изменит это позже, это усилит ваши предположения. void setFoo( Object foo ){ foo = foo; }
, где она должна быть void setFoo( Object foo ){ this.foo = foo; }
. (В первом случае foo
, который записывается в параметр , а не поле foo
объекта]. Из своих примеров :
final PojoValidator pojoValidator = new PojoValidator();
//create rules
pojoValidator.addRule( new NoPublicFieldsRule () );
pojoValidator.addRule( new NoPrimitivesRule () );
pojoValidator.addRule( new GetterMustExistRule () );
pojoValidator.addRule( new SetterMustExistRule () );
//create testers
pojoValidator.addTester( new DefaultValuesNullTester () );
pojoValidator.addTester( new SetterTester () );
pojoValidator.addTester( new GetterTester () );
//test all the classes
for( PojoClass pojoClass : PojoClassFactory.getPojoClasses( "net.initech.app", new FilterPackageInfo() ) )
pojoValidator.runValidation( pojoClass );
Я сделал небольшой анализ охвата, достигнутого в самом коде JUnit .
Одна категория непокрытого кода «слишком проста для проверки» . Это включает в себя простые геттеры и сеттеры, которые разработчики JUnit делают not .
С другой стороны, JUnit не имеет метода (non-debrecated) длиной более 3 линии, которые не охватываются никаким тестом.
Несмотря на обоснованные причины для свойств, существует общая идея объектно-ориентированного дизайна, заключающаяся в том, что разоблачение состояния участника через свойства является плохим дизайном. Статья Роберта Мартина об Открытом Закрытом Принципе расширяет это, заявляя, что Свойства поощряют связь и поэтому ограничивают возможность закрыть класс от модификации - если вы измените свойство, всем потребителям класса понадобится также измениться. Он квалифицирует, что подвергая переменные-члены не обязательно плохой дизайн, это может быть просто плохой стиль. Однако, если свойства доступны только для чтения, вероятность злоупотреблений и побочных эффектов меньше.
Лучший подход, который я могу предложить для модульного тестирования (и это может показаться странным), - это сделать как можно больше свойств защищенный или внутренний. Это предотвратит связь, не поощряя писать глупые тесты для геттеров и сеттеров.
Есть очевидные причины, по которым должны использоваться свойства чтения / записи, такие как свойства ViewModel, которые привязаны к полям ввода и т. Д.
Более практично, модульные тесты должны обеспечивать функциональность с помощью общедоступных методов. Если код, который вы тестируете, использует эти свойства, вы получаете бесплатное покрытие кода. Если окажется, что эти свойства никогда не будут подсвечиваться с помощью покрытия кода, существует очень сильная возможность:
Если вы пишете тесты для геттеров и сеттеров, вы получаете ложное ощущение охвата и не сможете определить, действительно ли свойства используются функциональным поведением.
Если цикломатическая сложность геттера и / или сеттера равна 1 (что они обычно есть), тогда ответ не будет, вы не должны.
Поэтому, если у вас нет SLA, для которого требуется 100% -ное покрытие кода, не беспокойтесь и сосредоточьтесь на тестировании важного аспекта вашего программного обеспечения.
P.S. Не забывайте различать геттеры и сеттеры даже в таких языках, как C #, где свойства могут казаться одинаковыми. Сложность сеттера может быть выше, чем у получателя, и, таким образом, проверять единичный тест.
Это была последняя тема между моей командой и я. Мы снимаем для покрытия 80% кода. Моя команда утверждает, что геттеры и сеттеры автоматически реализованы, и компилятор генерирует базовый код за кулисами. В этом случае, если генерируемый код не является навязчивым, на самом деле не имеет смысла тестировать код, создаваемый компилятором для вас. Мы также обсудили асинхронные методы, и в этом случае компилятор генерирует целую кучу кода за кулисами. Это другой случай и то, что мы тестируем. Длинный ответ короткий, поднимите его с вашей командой и решите для себя, если его стоит проверить.
Кроме того, если вы используете отчет о покрытии кода, подобный нам, вы можете добавить атрибут [ExcludeFromCodeCoverage]. Наше решение состояло в том, чтобы использовать это для моделей, которые имеют только свойства с использованием геттеров и сеттеров или самим свойством. Таким образом, это не повлияет на общий охват кода% при запуске отчета о покрытии кода, предполагая, что это то, что вы используете для расчета процентного охвата кода. Счастливое тестирование!
Рой Ошерове в своей знаменитой книге «Искусство модульного тестирования» говорит:
Свойства (getters / seters в Java) - хорошие примеры кода, который обычно не содержит никакой логики, и не требует тестирования. Но будьте осторожны: как только вы добавите какую-либо проверку внутри свойства, вы захотите проверить, проверена ли логика.
blockquote>
Позвольте мне уточнить:
Из Эффективно работает с устаревшим кодом 1:
Термин единичный тест имеет долгую историю разработки программного обеспечения. Общим для большинства концепций модульных тестов является идея, что они являются испытаниями в изоляции отдельных компонентов программного обеспечения. Какие компоненты? Определение варьируется, но при модульном тестировании мы обычно занимаемся большинством атомных поведенческих единиц системы. В процедурном коде единицы часто являются функциями. В объектно-ориентированном коде единицы являются классами.
blockquote>Обратите внимание, что с ООП, где вы найдете геттеры и сеттеры, единица - это класс, не обязательно индивидуальные методы.
Что такое хороший тест?
Все требования и тесты следуют форме Логика Хора :
{P} C {Q}
blockquote>Где:
{P}
является предварительным условием (, данным )C
является (, когда ){Q}
является постусловием (, затем )Затем следует максим :
Тестирование, а не реализация
blockquote>Это означает, что вы не должны проверять, как
C
достигает пост-состояния, вы должны проверить, что{Q}
является результатомC
.Когда дело доходит до ООП,
C
является классом. Таким образом, вы не должны тестировать внутренние эффекты, а только внешние эффекты.Почему бы не тестировать получатели и сеттеры в изоляции
У получателей и сеттеров может быть какая-то логика, но так долго эта логика не имеют внешнего эффекта - делая их компонентами bean-аксессуаров 2) тест должен будет заглянуть внутрь объекта и тем самым не только нарушить инкапсуляцию, но и протестировать реализацию.
Итак, вы должны 't тестирует получателей и сеттеров в изоляции. Это плохо:
Describe 'LineItem class' Describe 'setVAT()' it 'should store the VAT rate' lineItem = new LineItem() lineItem.setVAT( 0.5 ) expect( lineItem.vat ).toBe( 0.5 )
Хотя если
setVAT
выдаст исключение, соответствующий тест будет подходящим, так как теперь есть внешний эффект.Как вы должны тестировать геттеры и сеттеры?
Фактически нет смысла изменять внутреннее состояние объекта, если такое изменение не влияет на внешность, даже если такой эффект наступает позже.
Таким образом, тест для сеттеров и геттеров должен быть связан с внешним эффектом этих методов, а не с внутренними.
Например:
Describe 'LineItem class' Describe 'getGross()' it 'should return the net time the VAT' lineItem = new LineItem() lineItem.setNet( 100 ) lineItem.setVAT( 0.5 ) expect( lineItem.getGross() ).toBe( 150 )
Вы можете подумать для себя:
Подождите секунду, мы тестируем
blockquote>getGross()
здесь notsetVAT()
.Но если
setVAT()
, что тест все равно потерпит неудачу.1Feathers, M., 2004. Эффективно работает с устаревшим кодом. Prentice Hall Professional.
2Martin, R.C., 2009. Clean code: руководство по гибкому программному мастерству. Образование Пирсона.
Юмористический, но мудрый прием: Путь Testivus
«Напишите тест, который вы можете сегодня»
Тестирование геттеров / сеттеров может быть чрезмерным если вы опытный тестер, и это небольшой проект. Однако, если вы только начинаете изучать модульный тест, или эти геттеры / сеттеры могут содержать логику (например, пример [Art_f []], то было бы неплохо написать тесты.
На мой взгляд, покрытие кода - это хороший способ увидеть, пропустили ли вы какую-либо функциональность, которую вы должны покрыть.
Когда вы проверяете покрытие вручную с помощью его красивой раскраски, можно утверждать, что простые геттеры и сеттеры не нуждаются в проверке (хотя я всегда это делаю).
Когда вы только проверьте процент покрытия кода на свой проект, тогда процент покрытия, равный 80%, не имеет смысла. Вы можете проверить все логические части и забыть некоторые важные части. В этом случае только 100% означает, что вы протестировали весь ваш жизненно важный код (и весь нелогичный код). Как только это 99,9%, вы знаете, что что-то забыли.
Кстати: покрытие кода - это окончательная проверка, чтобы проверить, полностью ли вы тестировали класс. Но 100% охват кода не обязательно означает, что вы действительно протестировали все функциональные возможности этого класса. Поэтому модульные тесты всегда должны выполняться по логике класса. В конце вы запустите покрытие, чтобы узнать, не забыли ли вы что-нибудь. Когда вы сделали это правильно, вы попали на 100% в первый раз.
Еще одно: недавно работая в большом банке в Нидерландах, я заметил, что Sonar указала 100% -ный охват кода. Однако я знал, что чего-то не хватает. Проверяя процент заполнения кода на файл, он указал файл с меньшим процентом. Весь процент кодовой базы был таким большим, что в одном файле процент не отображался как 99,9%. Так что вы можете посмотреть на это ...