GWTTestCase: Testing a Private Method

567 Views Asked by At

I am new to GWT / Java and need some ideas on how to solve this (seems like it should be) simple problem.

I have a GWT object and I am trying to test a private method:

public class BarChart extends FlowPanel {

    public BarChart() {
        super();
        privateMethod();
    }

    privateMethod() { 
        //want to test this 
    }
}

I've tried JUnit but it needs to be a GWTTestCase since this object needs GWT.create(), and I've tried reflection but GWTTestCase doesn't support it.

2

There are 2 best solutions below

3
Manolo Carrasco Moñino On BEST ANSWER

In GWT client (included GWTTestCase), you can call private or protected methods using JSNI, this is known as the violator pattern

Given a class with a private method

package com.example;
public class MyClass {
  private MyObjectReturn myMethod(MyObjectParam param) {
     return null
  }
}

Create a jsni method and access it

native MyObjectReturn myViolatorMethod(MyClass instance, MyObjectParam param) /*-{
  return [email protected]::myMethod(*)(param);
}-*/;
0
pfranza On

I know that it isn't going to be the answer that you are looking for but unit testing private methods is bad form.

You should likely refactor your code such that the effects of the private method can be tested/observed via the public API.

Since the code sample you provided is so short it is difficult to offer specific strategies, but I can make some general statements about the use-case.

The best way to test a private method is via another public method. If this cannot be done, then one of the following conditions is true:

  1. private method is unreachable (dead) code
  2. There is a design smell near the class that you are testing; the private method should still be having an observable effect on the class
  3. The method that you are trying to test should not be private; Perhaps changing the visiblity of the method is perfectly acceptable in this instance.

Additionally you can separate the UI code from the application logic using the GWT UIBinder. Once the UI has been separated out, you can use JUnit tests to test the remaining code. GWTTestcases are only for classes that require GWT.create(...) and they run very slowly (compared to junit), so it is best to structure the code such that the majority of the tests can be done using junit and then use gwttestcase to cover the remainder. If you can achieve this structure then it opens up additional avenues for testing using easymock/mockito/reflection etc.