assertEquals vs assertSame JUnit 5 | Java Fresher
Fast recall
Quick revision
Core answer
equals() method — while `assertSame` checks reference identity — whether both references point to the exact same object (==). Two distinct objects with equal fields pass assertEquals but fail assertSame. You rarely need assertSame except for caches, singletons, or interned values.Interview-ready guide
Interview answer
The difference is value equality versus reference identity. assertEquals checks that two things are equal by value, and under the hood it calls the equals method. assertSame checks that two references point to the exact same object in memory, which is the double-equals comparison.
So if I create two separate Point objects with the same coordinates, assertEquals will say they're equal — assuming Point overrides equals — but assertSame will fail, because they're two distinct objects even though their fields match. In practice, assertEquals is what I want almost all the time, because I usually care that the values match, not that it's literally the same instance.
There's a subtle trap worth calling out. If a class doesn't override equals, then assertEquals falls back to the default Object equals, which is just identity. So assertEquals on two value-equal objects of a class without an equals override will fail, behaving like assertSame. The fix is to make the class a record, which auto-generates equals, or to override equals manually.
assertSame does have legitimate uses, but they're rare — they're about identity mattering. For example, testing that a cache returns the same cached instance on repeated calls, or that a singleton always hands back the same object, or interned values like enums. In those cases I genuinely want to assert it's the same reference.
assertEquals vs assertSame JUnit 5 | Java Fresher
Direct Answer
assertEquals checks value equality — it calls the objects' equals() method — while assertSame checks reference identity — whether both references point to the exact same object (==). Two distinct objects with equal fields pass assertEquals but fail assertSame. You rarely need assertSame except for caches, singletons, or interned values.
Deep Dive & Architecture
assertEquals asks whether two values are equal according to equals; assertSame asks whether two references point to one object. That makes assertEquals the normal choice for strings, records, value objects, and collections.
For example, two Point(2, 3) records are separate instances, so assertSame fails, but their generated value equality makes assertEquals pass. A class that does not override equals inherits identity-based equality from Object, so even assertEquals then fails for two different instances with identical fields. assertSame is useful only when identity is itself the promise, such as a cache returning the previously stored instance or a singleton returning one shared object.
Common Mistakes & Pitfalls
assertSamefor values. It fails for distinct objects with equal fields; useassertEquals.- No
equals()override.assertEqualsthen compares identity and fails unexpectedly — use a record or overrideequals. - Relying on
==for strings. String identity depends on interning; compare values withassertEquals. - Overusing
assertSame. Real identity needs are rare (caches, singletons).
Check your understanding
Answer these without looking back at the article.
- What is the Arrange-Act-Assert (AAA) pattern in unit testing?
- How do you use assertThrows to test exception scenarios in JUnit 5?
- How do you test floating point numbers in JUnit 5?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.