Est de Java assertEquals méthode fiable?
Je sais que ==
a quelques problèmes lorsque l'on compare les deux Strings
. Il semble que String.equals()
est une meilleure approche. Eh bien, je suis en train de faire JUnit test et j'ai tendance à utiliser assertEquals(str1, str2)
. Est-ce un moyen fiable pour affirmer deux Chaînes contiennent le même contenu? Je voudrais utiliser assertTrue(str1.equals(str2))
, mais alors vous n'obtenez pas l'avantage de voir quels sont les valeurs réelles et sont à l'échec.
Sur une note connexe, quelqu'un aurait-il un lien vers une page ou un thread qui explique clairement les problèmes avec str1 == str2
?
- Si vous n'êtes pas sûr, vous pouvez lire le code, ou la Javadoc. BTW, si vous voulez tester, ils sont le même objet que vous pouvez utiliser assertSame.
- Si str1 et str2 sont nulles, assertEquals() est vrai, mais assertTrue(str1.equals(str2)) lève une exception. Le premier exemple sera également imprimer un utile message d'erreur tel que le contenu de str1 et str2, la seconde ne l'est pas.
Vous devez vous connecter pour publier un commentaire.
Vous devriez toujours utilisation
.equals()
lorsque l'on compare lesStrings
en Java.JUnit appelle la
.equals()
méthode pour déterminer l'égalité dans la méthodeassertEquals(Object o1, Object o2)
.Donc, vous êtes définitivement à l'abri à l'aide de
assertEquals(string1, string2)
. (Parce queString
s sontObject
s)Voici un lien vers un excellent Stackoverflow question à l'égard de certaines différences entre
==
et.equals()
.assertEquals
utilise leequals
méthode de comparaison. Il est une autre d'affirmer,assertSame
, qui utilise le==
opérateur.De comprendre pourquoi
==
ne doit pas être utilisé avec des chaînes, vous devez comprendre ce que les==
: il fait un contrôle d'identité. C'est,a == b
vérifie sia
etb
reportez-vous à la même objet. Il est construit dans la langue, et son comportement ne peut pas être modifié par les différentes classes. Leequals
méthode, d'autre part, peuvent être remplacées par des classes. Alors que son comportement par défaut (dans leObject
classe) est de faire un contrôle d'identité à l'aide de la==
de l'opérateur, de nombreuses classes, y comprisString
, le remplacer au lieu de faire une "équivalence" vérifier. Dans le cas deString
, au lieu de vérifier sia
etb
font référence au même objet,a.equals(b)
vérifie si les objets auxquels ils se réfèrent sont à la fois des chaînes de caractères qui contiennent exactement les mêmes caractères.Temps analogie: imaginez que chaque
String
objet est un morceau de papier avec quelque chose d'écrit sur elle. Disons que j'ai deux morceaux de papier avec "Toto" écrit sur eux, et un autre avec "Bar" écrit sur elle. Si je prends les deux premiers morceaux de papier et l'utilisation==
de les comparer entre eux, il sera de retourfalse
parce que c'est essentiellement de se demander "est-ce le même morceau de papier?". Il n'a même pas à regarder ce qui est écrit sur le papier. Le fait que je suis en lui donnant deux morceaux de papier (plutôt que de le même deux fois) signifie qu'il sera de retourfalse
. Si j'utiliseequals
, cependant, laequals
méthode permettra de lire les deux morceaux de papier et de voir qu'ils disent la même chose ("Foo"), et sera donc de retourtrue
.Le peu qui obtient la confusion avec les Chaînes, c'est que le Java a une notion de "stage" les Chaînes, et c'est (effectivement) automatiquement effectuée sur tous les littéraux de chaîne dans votre code. Cela signifie que si vous avez deux équivalent littéraux de chaîne dans votre code (même s'ils sont dans des classes différentes) il sera en fait à la fois référence à la même
String
objet. Cela rend le==
opérateur de retourtrue
plus souvent que l'on pourrait attendre.En un mot, vous pouvez avoir deux objets String qui contiennent les mêmes caractères, mais qui sont différents objets (dans différents emplacements de mémoire). L'opérateur == vérifie que les deux références pointent vers le même objet (l'emplacement de la mémoire), mais la méthode equals() vérifie si les caractères sont les mêmes.
Généralement vous intéresse, si deux Chaînes de caractères contenant les mêmes caractères, pas de savoir si elles pointent vers le même emplacement de mémoire.
Oui, c'est utilisé tout le temps pour les tests. Il est très probable que le framework de test utilise .equals() pour les comparaisons de ce genre.
Ci-dessous est un lien expliquant la "chaîne de l'égalité erreur". Essentiellement, des chaînes de caractères en Java sont des objets, et lorsque vous comparez l'objet d'égalité, ils sont généralement en comparaison basée sur l'adresse de mémoire, et non pas par le contenu. De ce fait, les deux chaînes ne pas occuper la même adresse, même si leur contenu est identique, de sorte qu'ils ne correspondent pas correctement, même si elles ont le même lors de l'impression.
http://blog.enrii.com/2006/03/15/java-string-equality-common-mistake/
JUnit
assertEquals(obj1, obj2)
ne fait appelobj1.equals(obj2)
.Il y a aussi
assertSame(obj1, obj2)
qui neobj1 == obj2
(c'est à dire, vérifie queobj1
etobj2
sont la référence à la même exemple), est ce que vous essayez d'éviter.Si vous êtes fine.
http://leepoint.net/notes-java/data/strings/12stringcomparison.html
String
est unObject
en java, de sorte qu'il tombe dans la catégorie de règles de comparaison.