Skip to main content

๐Ÿš€ Demystifying JUnit Testing with Mockito & Spring Extensions

๐Ÿ‘‹ Before diving deep into testing, I always assumed:


"JUnit is just something you use with @Test… it just works!"

 

But once I actually started exploring test frameworks in real-world projects, I realized there's so much more behind the scenes.


So here’s a blog to clarify the confusion, make it visually digestible, and hopefully save you some debugging hours. Let’s roll! ๐Ÿง ✨


๐Ÿ” Step 1: What dependencies should I include for JUnit?

You may have seen these terms in your build.gradle:

testImplementation 'org.junit.jupiter:junit-jupiter:5.10.0' implementation 'com.example:some-library:1.2.3'

But wait... what’s the difference? ๐Ÿค”

implementation

  • This means: Include the library for both compile time AND runtime.

  • It will be packaged inside the final JAR/WAR.

  • Use it for things your production code needs.

๐Ÿงช testImplementation

  • This means: Use it only during test execution.

  • It will NOT be added to the production JAR/WAR.

  • Perfect for JUnit, Mockito, and other test libraries.

๐ŸŽฏ Rule of thumb:


If it’s only used in test code, stick with testImplementation.


๐Ÿงฉ Step 2: Mockito vs Spring Extension — When to Use What?

You might have seen these annotations:


@ExtendWith(MockitoExtension.class) // JUnit + Mockito

@SpringBootTest                    // Spring Integration Test

Let’s decode them:

๐Ÿงช Use @ExtendWith(MockitoExtension.class):

  • Ideal for pure unit tests.

  • You’re mocking everything and not relying on Spring context.

  • Example: Testing service logic with fake repositories.

๐Ÿงช Use @SpringBootTest:

  • This loads the full Spring context — all your beans!

  • Perfect for integration testing.

  • You’re testing real method calls, configs, and actual Spring beans.


๐Ÿง  Step 3: What about @Mock, @InjectMocks, and @MockBean?


Let’s simplify:

Annotation      Comes FromUse Case
@Mock        Mockito                       Mock a single class/bean
@InjectMocks        Mockito                Inject mocked dependencies into the real class
@MockBean         Spring             Replace a bean in the Spring context with a mock


๐Ÿ”ง Example:
@Service public class MyService { private final MyRepo repo; public MyService(MyRepo repo) { this.repo = repo; } public String getData() { return repo.fetch(); } }

@ExtendWith(MockitoExtension.class) class MyServiceTest { @Mock MyRepo mockRepo; @InjectMocks MyService service; // Test with mocked repo! }

๐Ÿง  If you're using @SpringBootTest, prefer @MockBean to mock actual Spring beans during integration.


๐Ÿ’ฅ Step 4: Why do my integration tests break after adding a config?

Let’s say you added a new config:


@Configuration public class PubSubConfig { @Bean public PubSubTemplate pubSubTemplate() { return new PubSubTemplate(...); // Requires real credentials } }

Suddenly... ๐Ÿ’ฃ Your tests are failing!

๐Ÿคฏ Why?

Because:

  • @SpringBootTest loads the entire Spring context.

  • It tries to initialize your new bean.

  • If it needs real credentials, BOOM — your test explodes.

๐Ÿ›  Fix?

@MockBean private PubSubTemplate pubSubTemplate;

This mocks the bean during testing and avoids loading the real implementation.

๐Ÿ“ Bonus Tip:
Spring test uses application-test.properties. If required values are missing there, config loading can fail too.


๐Ÿงช Step 5: @ParameterizedTest vs @Test


AnnotationRuns how many times?Purpose
        @Test    Once         For static, fixed tests
 @ParameterizedTest        Multiple       Repeats test for each input set

Example:
@ParameterizedTest @ValueSource(strings = {"Hello", "JUnit"}) void testWithParams(String input) { assertNotNull(input); }

๐Ÿ’ก Use @ParameterizedTest when the same logic needs to be tested against multiple inputs!



๐Ÿ”š Wrapping Up

This post hopefully saves you from chasing vague test errors across JUnit, Spring, and Mockito setups.

  • Use @MockBean when Spring tries to load a bean you don’t want in tests.

  • Use @ExtendWith(MockitoExtension.class) for isolated unit tests.

  • Use @SpringBootTest for real context-driven tests — but be mindful of config pitfalls!

  • Choose the right annotations for what you’re testing.


๐Ÿ—ฃ Have you faced crazy test failures or mocking nightmares lately? Share your stories or tricks in the comments — let’s learn together!


Until next time,
– Anand ☕ @ Java Bean Bag

Comments

Popular posts from this blog

๐Ÿ” Is final Really Final in Java? The Truth May Surprise You ๐Ÿ˜ฒ

๐Ÿ’ฌ “When I was exploring what to do and what not to do in Java, one small keyword caught my eye — final . I thought it meant: locked, sealed, frozen — like my fridge when I forget to defrost it.”   But guess what? Java has its own meaning of final… and it’s not always what you expect! ๐Ÿ˜… Let’s break it down together — with code, questions, confusion, jokes, and everything in between. ๐ŸŽฏ The Confusing Case: You Said It's Final... Then It Changed?! ๐Ÿซ  final List<String> names = new ArrayList <>(); names.add( "Anand" ); names.add( "Rahul" ); System.out.println(names); // [Anand, Rahul] ๐Ÿคฏ Hold on... that’s final , right?! So how on earth is it still changing ? Time to dive deeper... ๐Ÿง  Why Is It Designed Like This? Here’s the key secret: In Java, final applies to the reference , not the object it points to . Let’s decode this like a spy mission ๐Ÿ•ต️‍♂️: Imagine This: final List<String> names = new ArrayList <>(); Be...

๐ŸŒŸ My Journey – From Zero to Senior Java Tech Lead ๐ŸŒŸ

 There’s one thing I truly believe… If I can become a Java developer, then anyone in the world can. ๐Ÿ’ฏ Sounds crazy? Let me take you back. ๐Ÿ•“ Back in 2015… I had zero coding knowledge . Not just that — I had no interest in coding either. But life has its own plans. In 2016, I got a chance to move to Bangalore and joined a Java course at a training center. That’s where it all started — Every day, every session made me feel like: "Ohhh! Even I can be a developer!" That course didn’t just teach Java — it gave me confidence . ๐Ÿงช Two Life-Changing Incidents 1️⃣ The Interview That Wasn't Planned Halfway through my course, I had to urgently travel to Chennai to donate blood to a family member. After that emotional rollercoaster, I found myself reflecting on my skills and the future. The next day, as I was preparing for my move to Bangalore to complete the remaining four months of my course, I randomly thought — "Let me test my skills... let me just see...

๐ŸŽข Java Loops: Fun, Fear, and ForEach() Fails

๐ŸŒ€ Oops, I Looped It Again! — The Ultimate Java Loop Guide You Won't Forget “I remember this question from one of my early interviews — I was just 2 years into Java and the interviewer asked, ‘Which loop do you prefer and why?’” At first, I thought, “Duh! for-each is cleaner.” But then he grilled me with cases where it fails. ๐Ÿ˜ต That led me to explore all loop types, their powers, and their pitfalls. Let’s deep-dive into every major Java loop with examples &  real-world guidance so you'll never forget again. ๐Ÿ” Loop Type #1: Classic For Loop — “The Old Reliable” ✅ When to Use: You need an index You want to iterate in reverse You want full control over loop mechanics ✅ Good Example: List<String> names = List.of("A", "B", "C"); for (int i = 0; i < names.size(); i++) { System.out.println(i + ": " + names.get(i)); } ๐Ÿ”ฅ Reverse + Removal Example: List<String> item...