使用Class.forName()

时间:2018-06-14 15:16:03

标签: java selenium-webdriver reflection jvm cucumber

使用Java我正在为selenium测试实现一个Page Factory对象,该对象获取页面对象的名称并通过反射实例化它以供Cucumber步骤定义使用。我遇到的问题是下面的代码找不到声明的类。包含此代码的对象PageFactory和页面对象LoginPage都位于名为pages的包中。

 /**
 * This method take a string containing a Page Object class name (case-sensitive) and returns an instance of the Page Object.
 * This allows us to operate on pages without knowing they exist when we write step definitions.
 * @param choice String
 * @return Page Object cast as a Page
 */
public static Page getPage(String choice) {
    Page entity = null;

    try {
        entity = (Page) Class.forName(choice).newInstance();
    } catch (InstantiationException e) {
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }
    return entity;
}

我收到一个堆栈跟踪,其中java.lang.ClassNotFoundException: LoginPage作为错误的开头。如果我将实体创建更改为以下代码,那么它可以正常工作。

        private static String packageName = "pages";
        entity = (Page) Class.forName(packageName + "." + choice).newInstance();

问题在于我想组织我的页面。当我创建pages.mywebsite并在其中放置LoginPage时,PageFactory无法知道在哪里找到该文件。

撇开我可能有两个名称空间pages.mywebsitepages.myotherwebsite并且都有LoginPage对象的问题,如何在不声明确切包的情况下找到我想要的文件,以及只是说"看看这个包和下面的课程"?

2 个答案:

答案 0 :(得分:3)

您可以使用System.getProperty("java.class.path")获取类路径,将其拆分为File.pathSeparator,然后使用FileVisitor扫描结果。

答案 1 :(得分:0)

这就是我解决问题的方式。我将反射移至findPageInPackage方法中,并递归调用该方法以搜索目录。

此处的完整代码:https://github.com/dougnoel/sentinel/blob/master/src/main/java/com/dougnoel/sentinel/pages/PageFactory.java

/**
 * Returns a page object if it exists in the package searched.
 * @param pageName String the name of the page object class to instantiate
 * @param packageName String the name of the package to search
 * @return Page the page object if it exists, otherwise null
 */
private static Page findPageInPackage(String pageName, String packageName) {
    Page page = null;
    try {
        page = (Page) Class.forName(packageName + "." + pageName).newInstance();
    } catch (InstantiationException e) {
        log.trace("{}.{} Page Object creation failed.", packageName, pageName);
        log.trace("java.lang.InstantiationException: {}", e.getMessage());
    } catch (IllegalAccessException e) {
        log.trace("{}.{} Page Object creation failed.", packageName, pageName);
        log.trace("java.lang.IllegalAccessException: {}", e.getMessage());
    } catch (ClassNotFoundException e) {
        log.trace("{}.{} Page Object creation failed.", packageName, pageName);
        log.trace("java.lang.ClassNotFoundException: {}", e.getMessage());
    }

    return page;
}

/**
 * Returns the Page Object for the page name. This allows us to operate on pages
 * without knowing they exist when we write step definitions.
 * <p>
 * Searches any optional page object packages set with the pageObjectPackages system property, and 
 * then searches the defaultPackageName value.
 * <p>
 * <b>Example:</b>
 * <p>
 * <code>System.setProperty("pageObjectPackages", "pages.SharedComponent,pages.UserAdminTool");</code>
 * 
 * @param pageName String the name of the page in
 *                 <a href="https://en.wikipedia.org/wiki/Camel_case">Pascal
 *                 case</a>
 * @return Page the specific page object cast as a generic page object
 * @throws PageNotFoundException if page could not be built or retrieved.
 * @throws ConfigurationNotFoundException if the value is not found in the configuration file
 */
public static Page buildOrRetrievePage(String pageName) throws PageNotFoundException, ConfigurationNotFoundException {
    Page page = pages.get(pageName);
    final String errorMessage = "The page you want to test could not be built. At least one Page object package is required to run a test. Please add a pageObjectPackages property to your conf/sentinel.yml configuration file and try again.";
    if (page != null) {
        return page;
    } else {
        if (pageObjectPackagesList == null) {
            pageObjectPackagesList = ConfigurationManager.getPageObjectPackageList();
            if(pageObjectPackagesList == null) {
                throw new PageNotFoundException(errorMessage);
            }
        }

        for (String pageObjectPackage : pageObjectPackagesList) {
            log.trace("pageObjectPackage: " + pageObjectPackage);
            page = findPageInPackage(pageName, pageObjectPackage);
            if (page != null) {
                break; // If we have a page object, stop searching.
            }
        }
    }
    if(page == null) {
        throw new PageNotFoundException(errorMessage);
    }
    pages.put(pageName, page);
    return page;
}