-
Notifications
You must be signed in to change notification settings - Fork 0
Accessing objects
When testing things, you often have to access objects you don't have access to, because they are hidden implementation details, like private fields, DOM attached widgets, etc.
There are many way to access those kind of objects with gwt-test-utils. This page sums up every techniques you could use and when to use a specific one.
The most easy way to access a private field in a test is to make this field package protected and write the unit test in the same package as the declaring class. This is a standard Java technique ;-)
Assuming you have some view with a private button field, just remove the private
modifier on this field :
package com.googlecode.gwt.test.sample.client;
public class SampleView extends Composite {
Button button;
...
}
Write your unit test in the same package as the SampleView
class and you will able to access like it was public :
package com.googlecode.gwt.test.sample.client;
@GwtModule("com.googlecode.gwt.test.sample.Sample")
public class SampleViewTest extends GwtTest {
@Test
public void clickOnButtonShouldDisplayMessageInLabel() {
// Arrange
SampleView view = new SampleView();
// Act
Browser.click(view.button);
...
}
}
As often as possible ! It's the simplest way of accessing a field. But sometimes, you just can't make a field package protected :
-
When the class which declares the field you want an access to is in a third-party dependency.
-
When you're writing integration tests, which test a lot of components (like
SampleView
) coming from different packages. -
When for some design purpose, it's really important that this field stays
private
. -
When the object you want to access is actually not referenced using a class field. For example, the button could have been instanciated and added to the DOM in
SampleView
's constructor.
Accessing private field is possible using Java Reflection API. Classes from java.lang.reflect
are not emulated by GWT's compiler, so they are not usable in a GWTTestCase
subclass.
By chance, you can use it with gwt-test-utils ;-)
Assuming you have some view with a private button field :
package com.googlecode.gwt.test.sample.client;
public class SampleView extends Composite {
private Button button;
...
}
Since the Java Reflection API is not so userfriendly, gwt-test-utils provides some utilities to simplify it in the GwtReflectionUtils class. To access the button, just use :
package com.googlecode.gwt.test.sample.client;
@GwtModule("com.googlecode.gwt.test.sample.Sample")
public class SampleViewTest extends GwtTest {
@Test
public void clickOnButtonShouldDisplayMessageInLabel() {
// Arrange
SampleView view = new SampleView();
Button button = GwtReflectionUtils.getPrivateFieldValue(view, "button");
// Act
Browser.click(button);
...
}
}
As an alternative, you could use the great fest-reflect API, it would work to ;-)
Reflection is usefull when you want to access a private field of a class you cannot modify.
But you must be aware accessing private members violates the object encapsulation principle and make your test depending on implementation details that may change over time.
TODO
TODO
A natural way for identifying GWT's widgets is to set them an HTML idenfier. It's done this way :
button.getElement().setId("my-button");
But usually, you don't need HTML id on production. That's why GWT comes with a nice UIObject.ensureDebugId() feature to be able to set HTML ids only when debugging.
TODO
TODO