HtmlUnit类强制转换异常:TextPage无法强制转换为HtmlPage

时间:2014-05-21 04:55:27

标签: java spring htmlunit

我正在尝试使用spring MVC测试和HTMLUnit来测试我的网页。我需要获取Html页面,以便我可以在页面中设置值并提交它,但我得到以下异常。我怎样才能做到这一点?我正在以正确的方式前进吗?请考虑我,因为我是TDD的新手。

错误堆栈跟踪:

java.lang.ClassCastException: com.gargoylesoftware.htmlunit.TextPage cannot be cast to com.gargoylesoftware.htmlunit.html.HtmlPage
    at com.demo.htmlunit.test.LoginControllerHtmlUnitTest.userLoginTest(LoginControllerHtmlUnitTest.java:51)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
    at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
    at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
    at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:83)
    at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:233)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:87)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:176)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)

我的测试类是:

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.htmlunit.MockMvcWebConnection;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;

import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.HtmlForm;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import com.gargoylesoftware.htmlunit.html.HtmlPasswordInput;
import com.gargoylesoftware.htmlunit.html.HtmlSubmitInput;
import com.gargoylesoftware.htmlunit.html.HtmlTextInput;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
@WebAppConfiguration
public class LoginControllerHtmlUnitTest {
    @Autowired
    private WebApplicationContext context;

    private WebClient webClient;

    @Before
    public void setup() {
        System.out.println("In set Up");
        MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(context).build();
        webClient = new WebClient();
        webClient.setWebConnection(new MockMvcWebConnection(mockMvc));
    }

    @After
    public void cleanup() {
        this.webClient.closeAllWindows();
    }

    @Test
    public void userLoginTest() {
        try {
            // Load the Login Form
            System.out.println("In User Login Test");
            HtmlPage createLoginFormPage = webClient
                    .getPage("http://localhost:8080/htmlunitdemo/login");
            System.out.println("createLoginFormPage:"+createLoginFormPage);
            // Setting Values in the Login form
            HtmlForm form = createLoginFormPage.getHtmlElementById("loginForm");
            HtmlTextInput usernameInput = createLoginFormPage
                    .getHtmlElementById("username");
            usernameInput.setValueAttribute("admin");
            HtmlPasswordInput passwordInput = createLoginFormPage
                    .getHtmlElementById("passcode");
            passwordInput.setText("admin123");
            HtmlSubmitInput submit = form.getOneHtmlElementByAttribute("input",
                    "type", "submit");
            // Submitting Form
            HtmlPage newPage = submit.click();


            System.out.println("New Page:" + newPage.asXml());

        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}

的applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
    http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd"
    default-lazy-init="true">

    <context:component-scan base-package="com.demo.htmlunit.controller" />
    <mvc:annotation-driven />

    <bean id="viewResolver"
        class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/pages/" />
        <property name="suffix" value=".jsp" />
    </bean>
</beans>

5 个答案:

答案 0 :(得分:1)

HtmlSubmitInput submitBtn = currentPage.getFirstByXPath("//input[@value='Search']");

currentPage = submitBtn.click();

答案 1 :(得分:1)

问题在于HTML单元无法转换不完整的HTML页面(例如,一些关闭标签)。因此,我可以使用HTMLUnit软件包中包含的HTMLParser解决此错误(我使用的是2.36.0v)。 HTMLParser完成并处理这种类型的转换错误。

//Web client creation.
Page page = webClient.getPage(url);
HtmlPage tmpPage = HTMLParser.parseHtml(page.getWebResponse(), webClient.getCurrentWindow());
// use tmpPage here

答案 2 :(得分:0)

HtmlUnit并不关心applicationContext.xml或您的Java服务器代码。重要的是服务器生成的输出。如果输出是随机文本,那么HtmlUnit将假定它正在获取文本文件并将创建一个TextPage来处理它。如果输出是HTML,那么HtmlUnit将假定它正在获取HTML文件并创建一个HtmlPage来保存结果。根据你的问题,你显然需要后者。

因此请验证服务器应用程序(http://localhost:8080/htmlunitdemo/login)的输出,并确保输出有效的HTML代码。

答案 3 :(得分:0)

替换代码行:

 HtmlPage newPage = submit.click();

with:

 TextPage newPage = submit.click();

答案 4 :(得分:0)

我不知道我是否已经找到解决方案。当按钮为“提交”时发生错误,而不是按钮类型。 我通过添加一个按钮并执行来解决了这个问题。

HtmlElement buttonCustom = (HtmlElement) page.createElement("button");
            buttonCustom.setAttribute("type", "submit");
            buttonCustom.setAttribute("name", "submit");
            buttonCustom.setAttribute("value", "Load");
            form.appendChild(buttonCustom);