0

我有以下减速器代码,我正在尝试使用 PowerMock 对其进行测试。包 com.cerner.cdh.examples.reducer;

public class LinkReversalReducer extends TableReducer<Text, Text, ImmutableBytesWritable> {

    @Override
    protected void reduce(Text key, Iterable<Text> values, Context context) throws IOException, InterruptedException {

        StringBuilder inlinks = new StringBuilder();

        for (Text value : values) {
            inlinks.append(value.toString());
            inlinks.append(" ");
        }

        byte[] docIdBytes = Bytes.toBytes(key.toString());

        Put put = new Put(docIdBytes);

        put.add(WikiConstants.COLUMN_FAMILY_BYTES, WikiConstants.INLINKS_COLUMN_QUALIFIER_BYTES,
                Bytes.toBytes(inlinks.toString().trim()));

        context.write(new ImmutableBytesWritable(docIdBytes), put);
    }
}

以下是我为上述内容编写的测试:

@Test
public void testLinkReversalReducer() throws IOException, InterruptedException {

        Text key = new Text("key");
        @SuppressWarnings("rawtypes")
        Context context = PowerMockito.mock(Context.class);
        Iterable<Text> values = generateText();

        StringBuilder inlinks = new StringBuilder();

        for (Text value : values) {
            inlinks.append(value);
            inlinks.append(" ");
        }

        LinkReversalReducer reducer = new LinkReversalReducer();

        byte[] docIdBytes = Bytes.toBytes(key.toString());

        byte[] argument1 = WikiConstants.COLUMN_FAMILY_BYTES;
        byte[] argument2 = WikiConstants.INLINKS_COLUMN_QUALIFIER_BYTES;

        byte[] argument3 = Bytes.toBytes(inlinks.toString().trim());

        Put put = new Put(docIdBytes);
        put.add(argument1, argument2, argument3);

        reducer.reduce(key, values, context);

        Mockito.verify(context).write(new ImmutableBytesWritable(docIdBytes), put);
    }

    private List<Text> generateText() {
        Text value = new Text("AB");
        List<Text> texts = new ArrayList<Text>();
        texts.add(value);
        return texts;
    }
}

所以问题是我的 Mockito.verify(context).write(new ImmutableBytesWritable(docIdBytes), put); 似乎被调用了正确的值,而且我的 junit 结果显示 Invoked 和 Actual 给出了相同的响应。但测试似乎仍然失败。有人有线索吗 ?. 任何帮助,将不胜感激 :)

4

1 回答 1

0

这里的问题是,Put该类没有定义equals方法。因此,该verify方法认为实际Put传递给您的方法context.write内部与您的方法中组装LinkReversalReducer.reduce的预期不同。PuttestLinkReversalReducer

要解决此问题,您可以执行以下操作:

Mockito.verify(context).write(Mockito.eq(new ImmutableBytesWritable(docIdBytes)), MockitoHelper.eq(put));

...

class MockitoHelper {
    public static Put eq(final Put expectedPut) {
        return Mockito.argThat(new CustomTypeSafeMatcher<Put>(expectedPut.toString()) {
            @Override
            protected boolean matchesSafely(Put actualPut) {
                return Bytes.equals(toBytes(expectedPut), toBytes(actualPut));
            }
        });
    }

    private static byte[] toBytes(Put put) {
        ByteArrayDataOutput out = new ByteArrayDataOutput();
        try {
            put.write(out);
            return out.toByteArray();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}
于 2013-10-09T20:05:46.483 回答