英文:
Wicket Ajax test resetting DropDownChoice to null
问题
我正在尝试为我添加到DropDownChoice组件的Ajax行为设置单元测试。当我调用tester.executeAjaxEvent(…)时,DropDownChoice模型值被重置为“null”。我不理解wicket中ajax的工作原理。有人可以帮帮我吗?为什么触发“change”事件会导致组件将其模型设置为null。
DropDownPage.html
<?xml version="1.0" encoding="UTF-8"?>
<html>
<head>
<title>DropDownPage</title>
</head>
<body>
<form wicket:id="form">
<select wicket:id="dropDown">
<option>Option 1</option>
</select>
</form>
</body>
</html>
DropDownPage.java
public class DropDownPage extends WebPage {
// ... (其他代码)
public DropDownPage() {
// ... (其他代码)
dropDown.add(new AjaxFormComponentUpdatingBehavior("change") {
@Override
protected void onUpdate(AjaxRequestTarget target) {
// ... (其他代码)
}
});
form.add(dropDown);
}
// ... (其他代码)
}
TestDropDownAjax.java
public class TestDropDownAjax {
// ... (其他代码)
@Test
public void testDropDownPage() {
// ... (其他代码)
DropDownPage dropDownPage = new DropDownPage() {
// ... (其他代码)
};
DropDownChoice<String> dropDown = (DropDownChoice<String>) dropDownPage.get("form:dropDown");
assertNotNull(dropDown);
// ... (其他代码)
tester.executeAjaxEvent("form:dropDown", "change");
// ... (其他代码)
}
}
英文:
I am trying to set up a unit test for an Ajax behavior that I have added to a DropDownChoice component. When I make a call to tester.executeAjaxEvent(…) the DropDownChoice model value gets reset to “null”. I am not understanding something fundamental on how ajax works in wicket. Can anybody help me out here? Why is triggering the "change" event, causing the component to set it's model to null.
DropDownPage.html
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-html -->
<?xml version="1.0" encoding="UTF-8"?>
<html>
<head>
<title>DropDownPage</title>
</head>
<body>
<form wicket:id="form">
<select wicket:id="dropDown">
<option>Option 1</option>
</select>
</form>
</body>
</html>
<!-- end snippet -->
DropDownPage.java
public class DropDownPage extends WebPage {
private static final Logger log = LogManager.getLogger(DropDownPage.class);
public DropDownPage() {
Form<Void> form = new Form<Void>("form");
add(form);
DropDownChoice<String> dropDown = new DropDownChoice<String>("dropDown", new Model<String>(new String()), Arrays.asList(new String[] { "A", "B" }));
dropDown.setOutputMarkupId(true);
dropDown.add(new AjaxFormComponentUpdatingBehavior("change") {
@Override
protected void onUpdate(AjaxRequestTarget target) {
String choice = dropDown.getModelObject();
if (choice == null) {
nullCall(target);
return;
}
switch (choice) {
case "A":
doAStuff(target);
break;
case "B":
doBStuff(target);
break;
default:
unknownType(target);
}
}
});
form.add(dropDown);
}
protected void doAStuff(AjaxRequestTarget target) {
log.info("doAStuff(...)");
}
protected void doBStuff(AjaxRequestTarget target) {
log.info("doBStuff(...)");
}
protected void nullCall(AjaxRequestTarget target) {
log.info("nullCall(...)");
}
protected void unknownType(AjaxRequestTarget target) {
log.info("unknownType(...)");
}
}
TestDropDownAjax.java
public class TestDropDownAjax {
private WicketTester tester;
@Before
public void setup() throws Exception {
tester = new WicketTester();
}
@After
public void tearDown() {
tester.destroy();
}
int aCount = 0;
int nullCount = 0;
@SuppressWarnings("unchecked")
@Test
public void testDropDownPage() {
DropDownPage dropDownPage = new DropDownPage() {
@Override
protected void doAStuff(AjaxRequestTarget target) {
super.doAStuff(target);
++aCount;
}
@Override
protected void nullCall(AjaxRequestTarget target) {
super.nullCall(target);
++nullCount;
}
};
DropDownChoice<String> dropDown = (DropDownChoice<String>) dropDownPage.get("form:dropDown");
assertNotNull(dropDown);
List<String> choices = (List<String>) dropDown.getChoices();
String choice = choices.get(0);
dropDown.setModelObject(choice);
tester.startPage(dropDownPage);
tester.assertModelValue("form:dropDown", dropDown.getModelObject());
assertEquals(choice, dropDown.getModelObject());
assertEquals(0, nullCount);
assertEquals(0, aCount);
tester.executeAjaxEvent("form:dropDown", "change");
assertEquals(0, nullCount); // fails here
assertEquals(1, aCount);
}
}
答案1
得分: 2
AjaxFormComponentUpdatingBehavior
在调用您的update
方法之前,会调用内部方法inputChanged
。该方法尝试将最新的用户输入转换为下拉列表的新值。由于您实际上并没有输入任何新内容,这将被解释为选择空选项,导致模型值变为null
。
因此,您还需要通过WicketTester来进行表单输入。
一种方法是使用FormTester
:
FormTester formTester = tester.newFormTester("form");
formTester.select("dropDown", 0);
tester.executeAjaxEvent("form:dropDown", "change");
这将使您的测试通过。
英文:
The AjaxFormComponentUpdatingBehavior
, prior to calling your update
method, calls the internal method inputChanged
. This method tries to turn the latest user input into a new value for the dropdown's model. Since you didn't actually input anything new, this will be interpreted as selecting the empty option, causing the model value to become null
.
As such, you need to do the form input through WicketTester as well.
One way to do this, is through FormTester
:
FormTester formTester = tester.newFormTester("form");
formTester.select("dropDown", 0);
tester.executeAjaxEvent("form:dropDown", "change");
This will make your test pass.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论