Explain Codes LogoExplain Codes Logo

Difference Between @Mock and @InjectMocks

java
mockito
unit-testing
test-automation
Nikita BarsukovbyNikita Barsukov·Nov 7, 2024
TLDR

@Mock is a tool in Mockito that helps create mock objects. On the other hand, @InjectMocks is like your very own assembler, injecting these mocks into another object for testing. So when you mark a field as @InjectMocks, it treats the field like a perfect home and inserts every @Mock into a corresponding constructor, setter, or field of the home.

class TestClass { @Mock Dependency mockDependency; // Look Ma, no hands! Mock creation @InjectMocks ServiceUnderTest service; // Get out of the way; auto-mocking coming through! }

Mockito plays the matchmaker and automatically wires mockDependency into service for a happy ever after. This allows a nice, isolated testing of ServiceUnderTest, replacing real dependencies with loyal mocks.

Mockito annotations demystified

Unleash your JUnit

JUnit 4 folks, throw @RunWith(MockitoJUnitRunner.class) into your test class to get those mocks sprung to life. However, if you are cavorting with JUnit 5, usher in your mocks with @ExtendWith(MockitoExtension.class).

Type-safety for the WIN!

@Mock your worries away because Mockito's type-safe injection ensures that the objects get glued together based on matching field types. No eyeballing constructors or crafting setters needed!

The Spy who mocked me

When you need a dash of reality in your mock world, call in @Spy. @Spy teases out partial mocks: real objects that cavort on your command. Combine them with @InjectMocks to let Mockito do the auto-injection.

Mocks: The Spring Breakers

Longing for control? Swap @Autowired with @Mock in tests to puppeteer your injected dependencies. Dictate responses, verify antics, and define your test story.

Custom Mock Setup

If the cut-and-dried ain't your style, dive into setUp() realm and wave MockitoAnnotations.initMocks(this) wand for that extra control over mock initializations.

Mocking 101: From the trenches

Let's dig into some common practical scenarios, frequent pitfalls and best practices surrounding @Mock and @InjectMocks.

Mocking: Where and why?

  • Use @Mock for whisking away the external dependencies that dare disturb your peaceful class under test. Solo testing, here we come!
  • @InjectMocks is your magic carpet to populate the mocks within the class under trial. It's all about checking logic and leaving wiring by the wayside.

Beware, here be dragons

  • @InjectMocks compilation may fall flat if it locks horns with incompatible constructor requirements, leaving the injection incomplete. Stick with field injection to stay on the safe side.
  • Double-check before @Spy teams up with @InjectMocks; else, you might bump into unexpected real method calls. Stick with @Mock for undiluted mock behavior.

The Mockito way: Best practices

  • Consistency in using @Mock and @InjectMocks can streamline testing and give your test code a clean, crisp look.
  • Play Sherlock; always verify interactions with mocks to validate the expected behavior.
  • Discover and master Mockito wonders like ArgumentCaptor or Answer to harness its full potential.