2

I am trying to write some junit for a class which is using CountDownLatch and I am using jmockit library for junit testing.

public class MappedData {

    private static final AtomicReference<Map<String, Map<Integer, String>>> mapped1 = new AtomicReference<Map<String, Map<Integer, String>>>();
    private static final AtomicReference<Map<String, Map<Integer, String>>> mapped2 = new AtomicReference<Map<String, Map<Integer, String>>>();
    private static final CountDownLatch firstSet = new CountDownLatch(1);

    public static Map<String, Map<Integer, String>> getMapped1Table() {
    try {
        firstSet.await();
    } catch (InterruptedException e) {
        throw new IllegalStateException(e);
    }
    return mapped1.get();
    }

    public static Map<String, Map<Integer, String>> getMapped2Table() {
    try {
        firstSet.await();
    } catch (InterruptedException e) {
        throw new IllegalStateException(e);
    }
    return mapped2.get();
    }
}

What is the easiest way to make sure that in the getMapped1Table and getMapped2Table method - I am able to throw an InterruptedException so that I can cover that scenario as well. If you take a look into those two methods, I have a catch block which I am not able to cover.

MappedData.getMapped1Table()

Is there any way I can make sure that my above two methods are throwing InterruptedException?

Update:-

What I am trying to do is - how to get firstSet.await() to throw an InterruptedException when I am junit testing.

4

3 回答 3

1

这是使用 JMockit 编写测试的最简单方法:

public class MappedDataTest
{
    @Test
    public void getMappedTableHandlesInterruptedException(
        @Mocked final CountDownLatch anyLatch) throws Exception
    {
        final InterruptedException interrupt = new InterruptedException();
        new NonStrictExpectations() {{ anyLatch.await(); result = interrupt; }};

        try {
            MappedData.getMapped1Table();
            fail();
        }
        catch (IllegalStateException e) {
            assertSame(interrupt, e.getCause());
        }
    }
}
于 2014-04-15T20:59:03.657 回答
1

在一个单独的线程中调用该方法,然后中断该线程:

Thread t = new Thread(new Runnable(){
   public void run(){
      MappedData.getMappedTable();
    }
});

t.start();

t.interrupt();
于 2014-04-15T21:26:42.270 回答
0

您可以使用MockitoEasyMock等模拟库来完成。您将需要一种注入模拟依赖项的方法。通常这是通过构造函数完成的,但由于您的字段是static您可能想要添加一个 setter。

public static void setFirstSet(CountDownLatch latch)
{
    firstSet = latch;
}

此示例的其余部分适用于 Mockito。

在您的测试中,创建一个模拟CountDownLatch

CountDownLatch mockLatch = mock(CountDownLatch.class);

然后存根方法抛出异常:

when(mockLatch.await()).thenThrow(new InterruptedException());

接下来注入模拟:

MappedData.setFirstSet(mockLatch);

最后调用被测方法:

Map<String, Map<Integer, String>> result = MappedData.getMapped1Table();

我从未使用过 jmockit,但通过快速的谷歌搜索表明这是这样做的方法:

final CountDownLatch mockLatch = new CountDownLatch();
new Expectations(mockLatch){
    {
        mockLatch.await();
        result = new InterruptedException();
    }
};
MappedData.setFirstSet(mockLatch);
Map<String, Map<Integer, String>> result = MappedData.getMapped1Table();
于 2014-04-15T20:24:32.870 回答