为依赖类测试创建存根

时间:2014-09-07 15:20:01

标签: java unit-testing testing reflection

大家好!我有一个关于测试和生成存根以通过反射依赖的问题。因此,我们假设我有一个名为UnderTest的类:

class UnderTest{
/*field*/ 
SomeLogic someLogic; 
/*method, that i testing*/
List<MyObject> getCalculatedObjects(params) {/*logic,based on result getSomeStuff of someLogic*/    }
} 
class SomeLogic { 
List<String> getSomeStuff(String param) { /*Some complex and slow code, actually  don't want test this code, and want to use some reflection invocation handler*/ }
}

对我来说,重要的是不要更改遗留代码,而代码并不是为测试而设计的。我没有任何理由,除了测试将SomeLogic作为接口等等。 我不记得如何使用反射处理someLogic的方法调用。但谷歌搜索并没有帮助我。

Class MainAPI是我模块的主要API。 NetworkProvider长时间打开流操作,这就是我想在我的本地文件上存根的原因。但是不要在NetworkProvider上直接使用引用。再次抱歉我的英语。

public class MainAPI {
    private final XPath xPath;
    private final ItemParser itemParser;
    private final ListItemsParser listItemsParser;
    private final DateParser dateParser;
    private final HtmlCleanUp htmlCleanUp;

    private final NetworkProvider networkProvider;


    public MainAPI(XPath xPath, ItemParser itemParser, ListItemsParser listItemsParser, DateParser dateParser, HtmlCleanUp htmlCleanUp, NetworkProvider networkProvider) {
        this.xPath = xPath;
        this.itemParser = itemParser;
        this.listItemsParser = listItemsParser;
        this.dateParser = dateParser;
        this.htmlCleanUp = htmlCleanUp;
        this.networkProvider = networkProvider;
    }

    public MainAPI() throws XPathExpressionException, IOException {
        dateParser = new DateParser();
        xPath = XPathFactory.newInstance().newXPath();
        networkProvider = new NetworkProvider();
        listItemsParser = new ListItemsParser(xPath, dateParser, item -> true);
        itemParser = new ItemParser(xPath, dateParser, networkProvider);
        htmlCleanUp = new HtmlCleanUpByCleaner();
    }

    public List<Item> getItemsFromSessionParsing(SessionParsing sessionParsing) {
        listItemsParser.setCondition(sessionParsing.getFilter());
        List<Item> result = new ArrayList<>();
        Document cleanDocument;
        InputStream inputStream;
        for (int currentPage = sessionParsing.getStartPage(); currentPage <= sessionParsing.getLastPage(); currentPage++) {
            try {
                inputStream = networkProvider.openStream(sessionParsing.getUrlAddressByPageNumber(currentPage));
            } catch (MalformedURLException e) {
                e.printStackTrace();
                break;
            }
            cleanDocument = htmlCleanUp.getCleanDocument(inputStream);
            List<Item> list = null;
            try {
                list = listItemsParser.getList(cleanDocument);
            } catch (XPathExpressionException e) {
                e.printStackTrace();
                break;
            }
            for (Item item : list) {
                inputStream = null;
                try {
                    inputStream = networkProvider.openStream("http://www.avito.ru" + item.getUrl());
                } catch (MalformedURLException e) {
                    e.printStackTrace();
                    break;
                }
                cleanDocument = htmlCleanUp.getCleanDocument(inputStream);
                try {
                    item.setDescription(itemParser.getDescription(cleanDocument));
                } catch (XPathExpressionException e) {
                    e.printStackTrace();
                }

            }
            result.addAll(list);
        }
        return result;
    }
}

public class NetworkProvider {
    private final ListCycleWrapper<Proxy> proxyList;

    public NetworkProvider(List<Proxy> proxyList) {
        this.proxyList = new ListCycleWrapper<>(proxyList);
    }

    public NetworkProvider() throws XPathExpressionException, IOException {
        this(new ProxySiteParser().getProxyList(new HtmlCleanUpByCleaner().getCleanDocument(new URL("http://www.google-proxy.net").openStream())));
    }

    public int getSizeOfProxy() {
        return proxyList.size();
    }

    public InputStream openStream(String urlAddress) throws MalformedURLException {
        URL url = new URL(urlAddress);

        while (!proxyList.isEmpty()) {
            URLConnection con = null;
            try {
                con = url.openConnection(proxyList.getNext());
                con.setConnectTimeout(6000);
                con.setReadTimeout(6000);
                return con.getInputStream();
            } catch (IOException e) {
                proxyList.remove();
            }
        }
        return null;
    }
}

1 个答案:

答案 0 :(得分:1)

您的类的所有依赖项都可以使用它的构造函数进行注入,因此存在这些依赖项并注入存根不应该有任何问题。你甚至不需要反思。例如,使用Mockito:

NetworkProvider stubbedNetworkProvider = mock(NetworkProvider.class);
MainAPI mainApi = new MainAPI(..., stubbedNetworkProvider);

如果您愿意,也可以自己编写存根:

NetworkProvider stubbedNetworkProvider = new NetworkProvider(Collections.emptyList()) {
    // TODO override the methods to stub
};
MainAPI mainApi = new MainAPI(..., stubbedNetworkProvider);