【发布时间】:2018-06-14 15:16:02
【问题描述】:
使用 Java 我正在实现一个用于硒测试的页面工厂对象,该对象采用页面对象的名称并通过反射将其实例化以供 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.mywebsite 和pages.myotherwebsite 的问题不谈,它们都有一个LoginPage 对象,我怎样才能在不声明确切包的情况下找到我想要的文件,然后说“看看这个包和下面的类”?
【问题讨论】:
-
我想,
Page.forName(…)应该是Class.forName(…)?除此之外,你希望谁来决定pages.mywebsite.LoginPage或pages.myotherwebsite.LoginPage是正确的班级?神奇的独角兽? -
编辑了上面的代码。我实际上创建了自己的 forName() 方法来尝试解决我的问题。但出于本次讨论的目的,我将重新使用默认值。至于谁来决定,我认为解决方案是根据加载的现有页面对象通过目录结构来完成 - 保持在同一级别。
-
那么……
existingPage.getClass().getPackage().getName()+'.'+choice还是我错过了什么? -
没有现有的页面对象。我有 Page.forName() 因为我有一个我创建的静态 forName() 函数。我有一个循环引用问题。在知道包之前无法实例化页面对象,在创建页面对象之前无法知道包。这个想法是其他人将创建页面对象并将它们放在
pages包中的文件夹中,但我不知道它们或它们的文件夹结构。也许我应该以不同的方式来做这件事? -
在您之前的评论中,您说“我认为解决方案是根据已加载的现有页面对象通过目录结构来完成 - 保持在同一级别” ,所以我很惊讶你现在说没有现有的页面对象,如果没有现有的页面对象,那么“保持在同一级别”是什么意思?和什么一样?
标签: java selenium-webdriver reflection jvm cucumber