2016-06-08 151 views
0

我想按CPU时间排序所有Java线程。我使用ThreadMXBean通过线程ID获取线程的CPU时间。比较器用于排序线程标识。Java,单元测试嘲笑mxbean

public class ThreadStats{ 
    private static ThreadMXBean mxbean = ManagementFactory.getThreadMXBean(); 

    class ThreadCPUCompare implements Comparator<Long>{ 

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

而且我已经做了以下的单元测试:

@RunWith(MockitoJUnitRunner.class) 
public class ThreadStatsTest { 

@InjectMocks ThreadCPUCompare comperator = new ThreadStats().new ThreadCPUCompare(); 
@Mock ThreadMXBean mxbean; 

@Test 
public void threadCPUSortTest() { 
    Mockito.when(mxbean.getThreadCpuTime(1L)).thenReturn(3L); 
    Mockito.when(mxbean.getThreadCpuTime(2L)).thenReturn(2L); 
    Mockito.when(mxbean.getThreadCpuTime(3L)).thenReturn(4L); 
    Mockito.when(mxbean.getThreadCpuTime(4L)).thenReturn(1L); 

    List<Long>expectedList = new ArrayList<Long>(); 
    expectedList.add(3L); 
    expectedList.add(1L); 
    expectedList.add(2L); 
    expectedList.add(4L); 

    List<Long>actualList = new ArrayList<Long>(); 
    actualList.add(4L); 
    actualList.add(2L); 
    actualList.add(3L); 
    actualList.add(1L); 


    //Sorting of the actual list 
    Collections.sort(actualList, comperator); 

    assertEquals(expectedList, actualList); 
    } 
} 

,但我不能让测试工作。我想因为嘲笑不起作用。有人能告诉我如何解决单元测试吗?

+0

不知道,但你会不会需要调用'验证(MXBean的)'? – uniknow

回答

0

您的测试失败,因为模拟没有被注入。 Mockito不会注入到静态字段中,也不会注入到外部类中(例如您的案例中的ThreadStats类)。

你需要编写代码是这样的:

class ThreadCPUCompare implements Comparator<Long> 
{ 
    private ThreadMXBean mxbean; 

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

@RunWith(MockitoJUnitRunner.class) 
public class ThreadStatsTest 
{ 
    @Mock ThreadMXBean mxbean; 
    @InjectMocks Comparator comperator = new ThreadCPUCompare(); 

    @Test 
    public void threadCPUSortTest() { 
     // do your tests exactly as before 
    } 
} 

这样您就可以连线成产品代码的挑战,但是这是一个不同的锻炼,在那里我会推荐某种依赖注入(guice,spring,manual等取决于上下文和偏好)。编写测试

+0

或者,只要保持原样,并且不要模拟地写测试。在这种情况下,测试可以简单地使用两个或三个CPU时间之间已知关系的线程(比如'Thread.currentThread()'和一个'new Thread()')。嘲笑是过度评估和最好的避免,像这样的情况只能证实它。 –

+0

@Rogério,你真的认为创建真正的线程,并试图控制他们的CPU时间将是一个更优雅的解决方案比嘲弄对ThreadMXBean的依赖?在这种情况下请分享该解决方案。 –

+0

好的,我添加了我的答案。 –

0

一个简单方法如下,不再带着嘲弄涉及:

public class ThreadStatsTest { 
    Comparator<Long> comparator = new ThreadStats().new ThreadCPUCompare(); 

    @Test 
    public void orderThreadIdsFromLongestToShortestCPUTime() { 
     long longLivedThread = Thread.currentThread().getId(); // > 0 cpu time 
     long shortLivedThread = new Thread().getId(); // 0 cpu time 

     int longTimeFirst = comparator.compare(longLivedThread, shortLivedThread); 
     int sameTimes = comparator.compare(longLivedThread, longLivedThread); 
     int longTimeSecond = comparator.compare(shortLivedThread, longLivedThread); 

     assertEquals(-1, longTimeFirst); 
     assertEquals(0, sameTimes); 
     assertEquals(1, longTimeSecond); 
    } 
}