DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Newsletter
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Related

  • IntelliJ Integration for Mockito
  • Testing Business Programs Without Constructing Domain Objects
  • Why Standard Test Automation Misses the Failures That Matter in AI Agent Systems
  • More Tests, More Confidence? Test Suites Are Investment Portfolios

Trending

  • How You Clear Your HTML5 Canvas Matters
  • Part 2: Securing and Scaling Goose-to-Java Agent Traffic With agentgateway
  • Rebuilding Elasticsearch Under Load: Unsafe Watermarks and a Sampling Blind Spot
  • Batching Strategies: Throughput vs Latency in Practice

Draft This article hasn't been published, so readers can't see it.

In moderation This article is waiting for review, so readers can't see it yet.

Deleted This article has been deleted, so readers can't see it.

  1. DZone
  2. Testing, Deployment, and Maintenance
  3. Testing, Tools, and Frameworks
  4. Improve Your Tests With Mockito’s Capture

Improve Your Tests With Mockito’s Capture

By 
Nicolas Fränkel
·
Jul. 05, 15 · Tutorial
Post on X (opens in a new tab) Share on LinkedIn (opens in a new tab)
2.9K Views

Join the DZone community Save articles, join the discussion, and download Refcards and Trend Reports with a free account.

Join for free Already a member? Log in

Unit Testing mandates to test the unit in isolation. In order to achieve that, the general consensus is to design our classes in a decoupled way using DI. In this paradigm, whether using a framework or not, whether using compile-time or runtime compilation, object instantiation is the responsibility of dedicated factories. In particular, this means the new keyword should be used only in those factories.

Sometimes, however, having a dedicated factory just doesn’t fit. This is the case when injecting an narrow-scope instance into a wider scope instance. A use-case I stumbled upon recently concerns event bus, code like this one:

public class Sample {

    private EventBus eventBus;

    public Sample(EventBus eventBus) {
        this.eventBus = eventBus;
    }

    public void done() {
        Result result = computeResult()
        eventBus.post(new DoneEvent(result));
    }

    private Result computeResult() {
        ...
    }
}

With a runtime DI framework – such as the Spring framework, and if the DoneEvent had no argument, this could be changed to a lookup method pattern.

public void done() {
    eventBus.post(getDoneEvent());
}

public abstract DoneEvent getDoneEvent();

Unfortunately, the argument just prevents us to use this nifty trick. And it cannot be done with runtime injection anyway. It doesn’t mean the done() method shouldn’t be tested, though. The problem is not only how to assert that when the method is called, a new DoneEvent is posted in the bus, but also check the wrapped result.

Experienced software engineers probably know about the Mockito.any(Class) method. This could be used like this:

public void doneShouldPostDoneEvent() {
    EventBus eventBus = Mockito.mock(EventBus.class);
    Sample sample = new Sample(eventBus);
    sample.done();
    Mockito.verify(eventBus).post(Mockito.any(DoneEvent.class));
}

In this case, we make sure an event of the right kind has been posted to the queue, but we are not sure what the result was. And if the result cannot be asserted, the confidence in the code decreases. Mockito to the rescue. Mockito provides captures, that act like placeholders for parameters. The above code can be changed like this: 

public void doneShouldPostDoneEventWithExpectedResult() {
    ArgumentCaptor<DoneEvent> captor = ArgumentCaptor.forClass(DoneEvent.class);
    EventBus eventBus = Mockito.mock(EventBus.class);
    Sample sample = new Sample(eventBus);
    sample.done();
    Mockito.verify(eventBus).post(captor.capture());
    DoneEvent event = captor.getCapture();
    assertThat(event.getResult(), is(expectedResult));
}

At line 2, we create a new ArgumentCaptor. At line 6, We replace any() usage with captor.capture() and the trick is done. The result is then captured by Mockito and available through captor.getCapture() at line 7. The final line – using Hamcrest, makes sure the result is the expected one. 

Mockito unit test

Published at DZone with permission of Nicolas Fränkel. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • IntelliJ Integration for Mockito
  • Testing Business Programs Without Constructing Domain Objects
  • Why Standard Test Automation Misses the Failures That Matter in AI Agent Systems
  • More Tests, More Confidence? Test Suites Are Investment Portfolios

Partner Resources

×

Comments

Loading comments

The comments didn't load

Please try again in a moment.

Likes

Loading

The next likes didn't load. Please try again.

The likes didn't load

Please try again in a moment.

See who liked this

Log in or join DZone for free to see who liked this article.

Log in Join for free
  • RSS
  • X
  • Facebook

ABOUT US

  • About DZone
  • Support and feedback
  • Community research

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 215
  • Nashville, TN 37211
  • [email protected]

Let's be friends:

  • RSS
  • X
  • Facebook