Написание юнит-тестов на неизменность - PullRequest
0 голосов
/ 29 мая 2018

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

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

Например, скажем, я разработал класс скажем Digit, и у него есть метод с именем add.Итак, тестовый пример, который я пишу, -

@Test
public void test_add(){
    Digit zero = Digit.getInstance(); //ignore why i am using getinstance here

    Digit result = zero.add(new Random().nextInt());

    assertNotEqual (zero, result); //there is no equal method overridden in Digit class
}

Я предполагаю, что assertNotEqual будет проверять ссылку двух объектов (zero и result).Если обе ссылки разные, это означает, что операция, выполненная над объектом zero, вернула новый объект, а не старый.

Имеет ли это смысл?

Ответы [ 2 ]

0 голосов
/ 29 мая 2018

assertEquals / assertNotEquals проверка на равенство с использованием метода equals объектов.Это похоже на assertTrue(expected.equals(actual)).Если параметр равенства не переопределен, он будет проверять ссылки на объекты (хэш-код), но я бы не стал полагаться на это, так как это может нарушить ваш тест, если вы в конце концов реализуете метод equals.

Если вы хотите проверить, являются ли объекты одинаковыми (или нет), используйте assertSame / assertNoSame, который проверяет равенство ссылок, аналогично assertTrue(expected == actual).

Но дляпроверка на неизменность не только проверяет, возвращает ли какая-либо модифицирующая операция новый экземпляр, но также проверяет, что исходный объект все еще не изменился!

Один из способов сделать это - создать ссылочный объект (или клон)исходного объекта и дополнительно проверяют, что исходный объект все еще равен эталонному объекту после вызова add.

@Test
public void test_add(){
    Digit zero = Digit.getInstance();

    Digit goldenMaster = zero.clone(); //if clone is implemented
    //or this
    Digit goldenMaster = Digit.getInstance(); 

    Digit result = zero.add(new Random().nextInt());

    assertNotSame (zero, result); //use check for reference
    assertEquals(goldenMaster, zero); //check the original object is still unmodified
}

Но это требует от вас правильного выполнения равных.

0 голосов
/ 29 мая 2018

Я предполагаю, что assertNotEqual будет проверять ссылку на два объекта

Не предполагайте.Прочитайте Javadoc !Он говорит:

Утверждает, что два объекта не равны.Если это так, выдается ошибка AssertionError без сообщения.Если неожиданные и фактические равны нулю, они считаются равными.

Другими словами, для этого используется стандартный Object::equals(Object) метод проверки равенства.Это будет использовать == сравнение, только если это то, что делает соответствующий метод equals(Object) под капотом.


Чтобы ответить на ваш вопрос, проверка на zero == result не является ни необходимой, ни достаточной проверкойнеизменность.

  • zero плюс некоторое случайное целое число может быть равно нулю
  • Тот факт, что zero равно == или нет == до result, не доказывает, что zero состояние объекта не изменилось.

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

Единственный действительный способ проверки на (истинную) неизменность - это объединить проверку с (обязательно) знание того, что происходит «внутри коробки»;то есть проверка кода вашего Digit класса и тестирование белого ящика.

Другой альтернативный вариант - определить, что вы подразумеваете под «неизменяемостью» в терминах определенных внешне видимых атрибутов Digit;например, что toString() возвращает.(Но с этим подходом тоже есть проблемы ...)

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