0
0
JUnittesting~15 mins

assertSame and assertNotSame in JUnit - Deep Dive

Choose your learning style9 modes available
Overview - assertSame and assertNotSame
What is it?
assertSame and assertNotSame are testing methods used in JUnit to check if two references point to the exact same object in memory. assertSame passes if both references are identical, while assertNotSame passes if they are different objects. These assertions help verify object identity rather than just equality of content.
Why it matters
Without assertSame and assertNotSame, tests might only check if two objects look equal but miss if they are actually the same instance. This can hide bugs where different objects with the same data behave unexpectedly. Using these assertions ensures your code handles object references correctly, preventing subtle errors in programs.
Where it fits
Before learning assertSame/assertNotSame, you should understand basic JUnit assertions like assertEquals and how object references work in Java. After mastering these, you can explore more advanced assertions and mocking frameworks that rely on object identity checks.
Mental Model
Core Idea
assertSame and assertNotSame check if two variables point to the exact same object in memory, not just if their contents are equal.
Think of it like...
It's like checking if two people are actually the same person wearing different clothes (same identity), rather than just looking similar (equal appearance).
┌───────────────┐       ┌───────────────┐
│ Reference A   │──────▶│ Object X      │
└───────────────┘       └───────────────┘

┌───────────────┐       ┌───────────────┐
│ Reference B   │──────▶│ Object X      │
└───────────────┘       └───────────────┘

assertSame passes because both point to Object X.


┌───────────────┐       ┌───────────────┐
│ Reference A   │──────▶│ Object X      │
└───────────────┘       └───────────────┘

┌───────────────┐       ┌───────────────┐
│ Reference B   │──────▶│ Object Y      │
└───────────────┘       └───────────────┘

assertNotSame passes because they point to different objects.
Build-Up - 6 Steps
1
FoundationUnderstanding Object References in Java
🤔
Concept: Learn how variables in Java hold references to objects, not the objects themselves.
In Java, when you create an object, the variable stores a reference (like an address) to that object in memory. Two variables can point to the same object or to different objects with the same content.
Result
You understand that variables are pointers to objects, not the objects themselves.
Understanding references is key to grasping why assertSame checks identity, not just equality.
2
FoundationDifference Between Equality and Identity
🤔
Concept: Distinguish between objects being equal in content and being the exact same object.
Two objects can be equal if their data matches (using equals()), but they might be different instances in memory. Identity means both variables point to the same instance.
Result
You can tell when two objects are equal versus when they are identical.
Knowing this difference prevents confusion when tests fail because objects look equal but are not the same instance.
3
IntermediateUsing assertSame in JUnit Tests
🤔Before reading on: do you think assertSame checks object content equality or object identity? Commit to your answer.
Concept: assertSame verifies that two references point to the exact same object instance.
Example: Object obj1 = new String("test"); Object obj2 = obj1; assertSame(obj1, obj2); // Passes because both refer to the same object Object obj3 = new String("test"); assertSame(obj1, obj3); // Fails because different objects, even if equal content
Result
Tests pass only if both references are identical.
Understanding assertSame helps catch bugs where object identity matters, such as caching or singleton patterns.
4
IntermediateUsing assertNotSame in JUnit Tests
🤔Before reading on: do you think assertNotSame passes when two references point to equal objects or different objects? Commit to your answer.
Concept: assertNotSame passes if two references do NOT point to the same object instance.
Example: Object obj1 = new String("hello"); Object obj2 = new String("hello"); assertNotSame(obj1, obj2); // Passes because they are different objects Object obj3 = obj1; assertNotSame(obj1, obj3); // Fails because same object
Result
Tests pass only if references are different.
Using assertNotSame ensures your code does not unintentionally reuse the same object when it shouldn't.
5
AdvancedCommon Use Cases for assertSame/assertNotSame
🤔Before reading on: do you think assertSame is useful only for simple objects or also for complex patterns like singletons? Commit to your answer.
Concept: Learn when to apply these assertions in real testing scenarios like caching, singletons, or object pooling.
assertSame is useful to verify that a method returns the exact cached instance or singleton object. assertNotSame helps confirm that new objects are created when expected, avoiding unwanted sharing. Example: Singleton s1 = Singleton.getInstance(); Singleton s2 = Singleton.getInstance(); assertSame(s1, s2); // Ensures singleton returns same instance
Result
You can write tests that verify object reuse or creation patterns.
Knowing these use cases helps write more precise tests that catch subtle bugs in object management.
6
ExpertPitfalls and Performance Implications of Identity Checks
🤔Before reading on: do you think assertSame is always faster than assertEquals? Commit to your answer.
Concept: Explore how identity checks differ in performance and behavior from equality checks and when they might cause false confidence.
assertSame is a simple reference comparison, so it is very fast. However, relying only on assertSame can miss logical equality bugs if objects are different instances but should behave identically. Also, some frameworks or proxies create new instances that are equal but not identical, causing assertSame to fail unexpectedly. Example: List list1 = List.of("a", "b"); List list2 = List.of("a", "b"); assertSame(list1, list2); // Fails, even though contents equal assertEquals(list1, list2); // Passes
Result
You understand when identity checks are appropriate and their limits.
Knowing the tradeoffs prevents misuse of assertSame and helps choose the right assertion for the test goal.
Under the Hood
assertSame uses the Java '==' operator to compare two references, which checks if both point to the same memory address. This is a direct pointer comparison without invoking any methods. assertNotSame negates this check. This differs from assertEquals, which calls the equals() method to compare object content.
Why designed this way?
Java separates identity (==) and equality (equals()) to allow flexible object comparison. JUnit provides assertSame and assertNotSame to test identity explicitly, which is important for certain design patterns and performance optimizations. This separation avoids confusion and gives precise control over what the test verifies.
┌───────────────┐       ┌───────────────┐
│ Reference A   │──────▶│ Object X      │
└───────────────┘       └───────────────┘

Comparison: Reference A == Reference B?

If yes: assertSame passes
If no: assertNotSame passes
Myth Busters - 3 Common Misconceptions
Quick: Does assertSame check if two objects have the same content? Commit to yes or no.
Common Belief:assertSame checks if two objects are equal in content, like assertEquals.
Tap to reveal reality
Reality:assertSame checks if two references point to the exact same object instance, not just equal content.
Why it matters:Confusing these causes tests to fail unexpectedly or pass incorrectly, hiding bugs in object reuse or identity.
Quick: Can assertNotSame pass if two objects are equal but different instances? Commit to yes or no.
Common Belief:assertNotSame only passes if objects are different and not equal in content.
Tap to reveal reality
Reality:assertNotSame passes if references are different, regardless of content equality.
Why it matters:Misunderstanding this leads to wrong assumptions about object uniqueness and test coverage.
Quick: Is assertSame always faster and better than assertEquals? Commit to yes or no.
Common Belief:assertSame is always better because it is a simple reference check.
Tap to reveal reality
Reality:assertSame is faster but only checks identity; assertEquals checks logical equality and is necessary when content matters more than identity.
Why it matters:Using assertSame blindly can miss logical errors where different objects should behave the same.
Expert Zone
1
assertSame can fail when testing proxies or mocks that wrap original objects, even if logically identical.
2
Using assertSame in multithreaded tests requires caution because object references might change due to concurrency.
3
Some immutable objects are cached and reused by the JVM (like small integers or strings), making assertSame pass unexpectedly.
When NOT to use
Do not use assertSame when you want to verify logical equality of objects; use assertEquals instead. Avoid assertSame for value objects or data transfer objects where identity is irrelevant.
Production Patterns
In production, assertSame is often used to test singleton patterns, object caches, or factory methods that should return the same instance. assertNotSame is used to ensure new instances are created when expected, such as in cloning or builder patterns.
Connections
Object Equality (equals method)
complements
Understanding assertSame clarifies the difference between identity and equality, deepening comprehension of the equals contract in Java.
Singleton Design Pattern
builds-on
assertSame is essential to verify that singleton implementations return the same instance, ensuring correct pattern usage.
Pointer Comparison in Computer Science
same pattern
assertSame mirrors low-level pointer comparison, showing how high-level tests relate to fundamental memory concepts.
Common Pitfalls
#1Using assertSame to check if two objects have the same content.
Wrong approach:assertSame(obj1, obj2); // where obj1 and obj2 are different instances but equal content
Correct approach:assertEquals(obj1, obj2); // checks content equality
Root cause:Confusing object identity with object equality.
#2Assuming assertNotSame fails if objects are equal in content.
Wrong approach:assertNotSame(obj1, obj2); // fails because objects are equal
Correct approach:assertNotSame(obj1, obj2); // passes because references differ
Root cause:Misunderstanding that assertNotSame only checks reference difference, not content.
#3Using assertSame for value objects where identity is irrelevant.
Wrong approach:assertSame(valueObj1, valueObj2); // fails because different instances
Correct approach:assertEquals(valueObj1, valueObj2); // passes if values equal
Root cause:Not recognizing when identity checks are inappropriate.
Key Takeaways
assertSame and assertNotSame check if two references point to the exact same object instance, not just if their contents are equal.
Understanding the difference between object identity and equality is crucial for writing accurate and meaningful tests.
Use assertSame to verify object reuse patterns like singletons or caches, and assertNotSame to ensure new instances are created when expected.
Misusing these assertions can cause tests to pass or fail incorrectly, hiding bugs or causing confusion.
Knowing when to use identity checks versus equality checks improves test precision and code reliability.