Koen
Koen

Reputation: 15

Unit test a method with mocking

I want to unit test this method. I know i need to mock the mxbean, but i have no idea how to do that. Could someone show me how to unit test this method please?

@Override
public int compare(Long threadId1, Long threadId2) {
    ThreadMXBean mxbean = ManagementFactory.getThreadMXBean();
    return Long.compare(mxbean.getThreadCpuTime(threadId2), mxbean.getThreadCpuTime(threadId1));
}

Upvotes: 0

Views: 258

Answers (1)

Sean Patrick Floyd
Sean Patrick Floyd

Reputation: 299148

As it is, it can't effectively be mocked. You need to move the local variable to a field.

ThreadMXBean mxbean = ManagementFactory.getThreadMXBean();

@Override
public int compare(Long threadId1, Long threadId2) {
    return Long.compare(mxbean.getThreadCpuTime(threadId2), mxbean.getThreadCpuTime(threadId1));
}

Now you can reassign the field to a mock in your test (I'll be using Mockito, but other frameworks exist as well):

@Test
public void yourTestMethod(){
    YourClass yourClass = new YourClass();
    ThreadMXBean mock = Mockito.mock(ThreadMXBean.class)
    Mockito.when(mxbean.getThreadCpuTime(1L)).thenReturn(1);
    Mockito.when(mxbean.getThreadCpuTime(2L)).thenReturn(2);
    yourClass.mxbean = mock;
    assertThat(yourClass.compare(1L, 2L), is(-1));
}

But it's even nicer to use the Mockito JUnit Runner and have Mockito create mocks automatically:

@RunWith(MockitoJUnitRunner.class)
public class YourTest{

    @InjectMocks YourClass yourClass = new YourClass();
    @Mock ThreadMXBean mock;

    @Test
    public void yourTestMethodDoesntNeedToCreateMocksAnymore(){
        Mockito.when(mxbean.getThreadCpuTime(1L)).thenReturn(1);
        Mockito.when(mxbean.getThreadCpuTime(2L)).thenReturn(2);
        assertThat(yourClass.compare(1L, 2L), is(-1));
    }


}

Finally: test get more readable if you replace all Mockito.* calls with static imports, e.g.

MyFoo foo = mock(MyFoo.class);
when(foo.bar()).thenReturn(baz);

Upvotes: 1

Related Questions