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
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Last call! Secure your stack and shape the future! Help dev teams across the globe navigate their software supply chain security challenges.

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

Releasing software shouldn't be stressful or risky. Learn how to leverage progressive delivery techniques to ensure safer deployments.

Avoid machine learning mistakes and boost model performance! Discover key ML patterns, anti-patterns, data strategies, and more.

Related

  • IntelliJ Integration for Mockito
  • Unit Testing Static Methods With Mockito
  • How to Unit Test Classes Which Create New Objects
  • How to Migrate From JUnit 4 to JUnit 5 Step by Step

Trending

  • Docker Base Images Demystified: A Practical Guide
  • AI Meets Vector Databases: Redefining Data Retrieval in the Age of Intelligence
  • Accelerating AI Inference With TensorRT
  • Doris: Unifying SQL Dialects for a Seamless Data Query Ecosystem
  1. DZone
  2. Testing, Deployment, and Maintenance
  3. Testing, Tools, and Frameworks
  4. Unit Testing Using Mockito and PowerMock

Unit Testing Using Mockito and PowerMock

We take a look at these two great testing frameworks to see how they can help with a myriad of unit testing use cases.

By 
Murat Derman user avatar
Murat Derman
·
Jan. 01, 19 · Tutorial
Likes (3)
Comment
Save
Tweet
Share
41.7K Views

Join the DZone community and get the full member experience.

Join For Free

Hey all, today I will talk about how we can mock and spy on methods for testing purposes using Mochito and PowerMock.

First of all, we need to set up MockitoAnntations before running our tests.

We just use the @Before annotation to run our initializations before the test runs.

@Before
public void setUp() throws Exception {
    MockitoAnnotations.initMocks(this);
}

when...thenReturn and when...thenAnswer Patterns

So let's start with mocking a service method which has to return an object. In order to do that, we can use the when...thenReturn or when...thenAnswer patterns

 In order to enable Mock and Spy injections, the service, which will inject them, has to be defined with the   @InjectMock annotation.

@InjectMocks
BatchServiceImpl batchServiceImpl

Mocked services are defined with the@Mock annotation

@Mock
ControlService controlService;

@Mock
PersistDataService persistDataService;

@Mock
FetchDataService fetchDataService;

With the help of the when... thenReturn pattern we can stub our method execution. See the example below

@Test
public void test_001()
{

    FetchDataResponse fetchDataResponse=new FetchDataResponse();
    fetchDataResponse.setResultCode(-1);
    when(fetchDataService.fetchSomeDataWithResponse(Mockito.any(FetchDataRequest.class)))
            .thenReturn(fetchDataResponse);


BaseResponse baseResponse = batchServiceImpl.executeBatchServices();

    if(baseResponse.getResultCode()==-1)
        Assert.assertTrue(true);
    else
        Assert.assertTrue(false);

}

We can also use the when...thenAnswer pattern for these kinds of cases. One difference between when... thenReturnand when... thenAnswer is that with when...thenAnswer we can vary the value returned every time a stubbed method is executed. See this code sample:

when(fetchDataService.fetchSomeDataWithResponse(Mockito.any(FetchDataRequest.class)))
        .thenAnswer(invocationOnMock -> {
            FetchDataResponse fetchDataResponse=new FetchDataResponse();
            fetchDataResponse.setRandomNumber(UUID.randomUUID().toString());
            fetchDataResponse.setResultCode(-1);
            return fetchDataResponse;
        });
}

The second difference is that you can use your inputs inside your stubbed method. See the below example:

when(fetchDataService.fetchSomeDataWithResponse(Mockito.any(FetchDataRequest.class)))
        .thenAnswer(invocationOnMock -> {
            Object[] arguments = invocationOnMock.getArguments();
            FetchDataResponse fetchDataResponse=new FetchDataResponse();

            FetchDataRequest request = (FetchDataRequest)arguments[0];
            if(request.getProcessStatus()=.INITIAL.getStatus())
                fetchDataResponse.setResultCode(-2);
            else
            fetchDataResponse.setResultCode(-1);
            return fetchDataResponse;
        });

Verify Method Executions and Evaluate the Inputs

If you want to evaluate your inputs, you have to use Mochito.verify and ArgumentCaptor. See the example code below:

@Test
public void test_003()
{
    when(fetchDataService.fetchSomeDataWithResponse(Mockito.any(FetchDataRequest.class)))
            .thenAnswer(invocationOnMock -> {
                FetchDataResponse fetchDataResponse=new FetchDataResponse();

                fetchDataResponse.setResultCode(-1);
                return fetchDataResponse;
            });


    batchServiceImpl.executeBatchServices();

    ArgumentCaptor<FetchDataRequest> fetchDataRequestCaptor = ArgumentCaptor.forClass(FetchDataRequest.class);
    Mockito.verify(fetchDataService).fetchSomeDataWithResponse(fetchDataRequestCaptor.capture());
    FetchDataRequest inputRequest = fetchDataRequestCaptor.getValue();


    if (inputRequest.getRowSize() != 1000)
        Assert.assertTrue(false);
    else if (inputRequest.getProcessStatus() != ProcessStatusEnum.INITIAL.getStatus())
        Assert.assertTrue(false);
    else
        Assert.assertTrue(true);
}

While verifying your execution via Mockito.verify, you can also check how many times your  method was executed by using Mockito.times or Mockito.never.

Mockito.verify(fetchDataService,Mockito.times(1)).fetchSomeDataWithResponse(fetchDataRequestCaptor.capture());

Mocking Void Methods

If you need to mock void methods, you can use Mockito.doAnswer. See the example below:

Mockito.doAnswer((i) -> {
    return null;
}).when(persistDataService).persist(Mockito.any(FetchDataRequest.class));

Let's say that you have a void method and you need to set its value to your input object. You can do so like this:

Mockito.doAnswer((i) -> {
    FetchDataDto fetchDataDto=new FetchDataDto();
    fetchDataDto.setId(1l);
    fetchDataDto.setName("Mike");
    fetchDataDto.setSurName("Howard");
    fetchDataDto.setAddressInfo("Chicago");
    List <FetchDataDto> fetchDataDtoList=new ArrayList<>();
    fetchDataDtoList.add(fetchDataDto);
    ((FetchDataRequest)i.getArgument(0)).setFetchDataDtoList(fetchDataDtoList);

    return null;
}).when(fetchDataService).fetchSomeData(Mockito.any(FetchDataRequest.class));

Throwing Exceptions in Mock Methods

If your real method is throwing an exception in some cases, and if you need to test the business logic after the exception occurs, you can mock the method like this:

Mockito.doThrow(new TraceServiceException(ErrorTypeEnum.BOOSTER_EXCEPTION.getErrorCode(),"Error Occured")).when(actionHandlerService).dispatchData(any(DailyFeedBackRequest.class));

Spy on Methods

Sometimes you need to run the real method, verify the execution, and evaluate the inputs. You can do partial mocking for this by using the Spy functionality .

You can define an interface and define spy for its implementation in the initialization phase and verify the execution and evaluate of the inputs in the test code.

    @Before
    public void setUp() throws Exception {
         persisDataService = spy(new PersistDataServiceImpl());

        MockitoAnnotations.initMocks(this);
    }


  @Test
    public void test_011() throws Exception {
        Mockito.doAnswer((i) -> {
            FetchDataDto fetchDataDto=new FetchDataDto();
            fetchDataDto.setId(1l);
            fetchDataDto.setName("Mike");
            fetchDataDto.setSurName("Howard");
            fetchDataDto.setAddressInfo("Chicago");
            List <FetchDataDto> fetchDataDtoList=new ArrayList<>();
            fetchDataDtoList.add(fetchDataDto);
            ((FetchDataRequest)i.getArgument(0)).setFetchDataDtoList(fetchDataDtoList);

            return null;
        }).when(fetchDataService).fetchSomeData(Mockito.any(FetchDataRequest.class));
        when(controlService.makeSomeCheck(Mockito.any(FetchDataRequest.class)))
                .thenAnswer(invocationOnMock -> {
                    BaseResponse baseResponse=new BaseResponse();
                    baseResponse.setResultCode(0);
                    return baseResponse;
                });
        batchServiceImpl.executeBatchServices();
        verify(persisDataService).spyMethod(any(FetchDataRequest.class));
    }

Mocking Private Methods

If your project contains private methods to test, you can’t use Mockito as it does not mock private methods. On the other hand, we can use the Powermock framework which provides us this functionality with Whitebox.invokeMethod.

@Test
public void test_009()
{
    try {

        Object obj = Whitebox.invokeMethod(batchServiceImpl, "makeTheChecks", any(FetchDataRequest.class));
        BaseResponse baseResponse = (BaseResponse) obj;
        if (baseResponse.getResultCode() == 0)
            Assert.assertTrue(true);
    } catch (Exception ex) {
        Assert.assertTrue(false);
    }

}
unit test Mockito

Opinions expressed by DZone contributors are their own.

Related

  • IntelliJ Integration for Mockito
  • Unit Testing Static Methods With Mockito
  • How to Unit Test Classes Which Create New Objects
  • How to Migrate From JUnit 4 to JUnit 5 Step by Step

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

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 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!