Java,单元测试模拟 mxbean
Java, unit test mocking mxbean
我想在 CPU 时间对所有 Java 线程进行排序。我使用 ThreadMXBean 通过线程 ID 获取线程的 CPU 时间。比较器用于对线程 ID 进行排序。
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);
}
}
但我无法让测试正常工作。我认为是因为嘲笑不起作用。有人可以告诉我如何修复单元测试吗?
您的测试失败,因为没有注入模拟。 Mockito 不会注入静态字段,也不会注入外部 class(例如您的 ThreadStats
class)。
你需要这样写代码:
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、手册等,具体取决于上下文和首选项)。
编写测试的一种简单方法如下,不涉及模拟:
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);
}
}
我想在 CPU 时间对所有 Java 线程进行排序。我使用 ThreadMXBean 通过线程 ID 获取线程的 CPU 时间。比较器用于对线程 ID 进行排序。
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);
}
}
但我无法让测试正常工作。我认为是因为嘲笑不起作用。有人可以告诉我如何修复单元测试吗?
您的测试失败,因为没有注入模拟。 Mockito 不会注入静态字段,也不会注入外部 class(例如您的 ThreadStats
class)。
你需要这样写代码:
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、手册等,具体取决于上下文和首选项)。
编写测试的一种简单方法如下,不涉及模拟:
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);
}
}