Является ли метод Java assertEquals надежным?

Я знаю, что == имеет некоторые проблемы при сравнении двух Strings. Кажется, что String.equals() - лучший подход. Ну, я тестирую JUnit, и я склонен использовать assertEquals(str1, str2). Это надежный способ утверждать, что две строки содержат один и тот же контент? Я использовал бы assertTrue(str1.equals(str2)), но тогда вы не получите преимущества, чтобы увидеть, что ожидаемые и фактические значения находятся в состоянии сбоя.

В какой-либо заметке кто-нибудь имеет ссылку на страницу или поток, которые явно объясняют проблемы с str1 == str2?

Ответ 1

Вы должны всегда использовать .equals() при сравнении Strings в Java.

JUnit вызывает метод .equals() для определения равенства в методе assertEquals(Object o1, Object o2).

Итак, вы определенно безопасны, используя assertEquals(string1, string2). (Потому что String Object s)

fooobar.com/questions/37055/... относительно некоторых различий между == и .equals().

Ответ 2

assertEquals использует метод equals для сравнения. Существует другое утверждение, assertSame, которое использует оператор ==.

Чтобы понять, почему == не следует использовать со строками, вам нужно понять, что делает ==: он выполняет проверку личности. То есть a == b проверяет, ссылаются ли теги a и b на один и тот же объект. Он встроен в язык, и его поведение не может быть изменено различными классами. С другой стороны, метод equals может быть переопределен классами. Хотя его поведение по умолчанию (в классе Object) заключается в выполнении проверки идентификатора с помощью оператора ==, многие классы, включая String, переопределяют его, вместо этого выполняют проверку эквивалентности. В случае String вместо проверки, что a и b относятся к одному и тому же объекту, a.equals(b) проверяет, являются ли объекты, на которые они ссылаются, обе строки, которые содержат точно такие же символы.

Время аналогии: представьте, что каждый объект String является листом бумаги с чем-то написанным на нем. Скажем, у меня есть два листа бумаги с надписью "Foo", а другой - с надписью "Bar". Если я возьму первые два листа бумаги и использую ==, чтобы сравнить их, он вернет false, потому что он по существу спрашивает: "Это тот же самый лист бумаги?". Не нужно даже смотреть на то, что написано на бумаге. Тот факт, что я даю ему два листа бумаги (а не один и тот же дважды), означает, что он вернет false. Однако, если я использую equals, метод equals будет читать два листа бумаги и видеть, что они говорят то же самое ( "Foo" ), и поэтому он вернет true.

Бит, который запутывается со строками, заключается в том, что Java имеет концепцию "интернирования" строк, и это (эффективно) автоматически выполняется на любых строковых литералах в вашем коде. Это означает, что если в вашем коде есть два эквивалентных строковых литерала (даже если они находятся в разных классах), они фактически будут ссылаться на один и тот же объект String. Это приводит к тому, что оператор == возвращает true чаще, чем можно было бы ожидать.

Ответ 3

В двух словах - вы можете иметь два объекта String, которые содержат одни и те же символы, но разные объекты (в разных ячейках памяти). Оператор == проверяет, что две ссылки указывают на один и тот же объект (ячейка памяти), но метод equals() проверяет, совпадают ли символы.

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

Ответ 4

Да, он используется все время для тестирования. Весьма вероятно, что в рамках тестирования используется .equals() для таких сравнений.

Ниже приведена ссылка, объясняющая "ошибку равенства строк". По сути, строки в Java являются объектами, и когда вы сравниваете равенство объектов, их обычно сравнивают по адресу памяти, а не по контенту. Из-за этого две строки не будут занимать один и тот же адрес, даже если их содержимое идентично, поэтому они не будут корректно совпадать, даже если они выглядят одинаково при печати. ​​

http://blog.enrii.com/2006/03/15/java-string-equality-common-mistake/

Ответ 5

public class StringEqualityTest extends TestCase {
    public void testEquality() throws Exception {
        String a = "abcde";
        String b = new String(a);
        assertTrue(a.equals(b));
        assertFalse(a == b);
        assertEquals(a, b);
    }
}

Ответ 6

JUnit assertEquals(obj1, obj2) действительно вызывает obj1.equals(obj2).

Там также assertSame(obj1, obj2), который делает obj1 == obj2 (то есть проверяет, что obj1 и obj2 ссылаются на один и тот же экземпляр), чего вы пытаетесь избежать.

Итак, ты в порядке.

Ответ 7

"Оператор == проверяет, являются ли два Objects точно такими же Object."

http://leepoint.net/notes-java/data/strings/12stringcomparison.html

String является Object в java, поэтому он попадает в эту категорию правил сравнения.