2016-06-08 203 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); 
    } 
}