实例化最终unmockable类的单元测试方法

时间:2016-05-10 12:06:10

标签: java android unit-testing mocking android-sqlite

这有点特定于Android,但它适用于非Android项目。

我有这个类将FilterEntity映射到ContentValuesFilterEntity是我创建和控制的数据结构,而ContentValues是来自Android SDK的最终类,如果没有模拟,则会抛出RuntimeException

public class FilterEntityToContentValuesMapper {

    public ContentValues mapOrThrow(FilterEntity filter) {
        final ContentValues values = new ContentValues();

        values.put(FilterSchema.COLUMN_ID, filter.id().toString());
        values.put(FilterSchema.COLUMN_NAME, filter.name());
        // and others...

        return values;
    }
}

经过测试ContentValues#put会立即抛出RuntimeException因为它没有被嘲笑,但问题在于它不能被嘲笑有两个原因。第一个ContentValues是最终的,第二个是在方法体中实例化的。

为了解决第一个问题,我创建了ContentValuesWrapper,它提供了与ContentValues完全相同的功能,但将所有内容委托给真正的ContentValues对象。对于第二个问题,我制作了ContentValuesWrapperFactory,其中提供了ContentValuesWrapper的实例。最终结果如下:

public class FilterEntityToContentValuesMapper {

    private final ContentValuesWrapperFactory contentValuesWrapperFactory;

    public FilterEntityToContentValuesMapper(ContentValuesWrapperFactory contentValuesWrapperFactory) {
        this.contentValuesWrapperFactory = contentValuesWrapperFactory;
    }        

        public ContentValues mapOrThrow(FilterEntity filter) {
            final ContentValuesWrapper values = contentValuesWrapperFactory.createContentValuesWrapper();

            values.put(FilterSchema.COLUMN_ID, filter.id().toString());
            values.put(FilterSchema.COLUMN_NAME, filter.name());
            // and others...

            return values;
        }
    }

我想知道是否有更好的解决方法,因为我正在使用ContentValuesWrapper复制功能。

1 个答案:

答案 0 :(得分:0)

看一下power mock https://github.com/jayway/powermock/wiki/MockFinal

也许你可以使用它而不是包装你的类