Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to mock static method in overlay type like JsDate.Create()? #41

Open
AlexLuya opened this issue Sep 4, 2014 · 2 comments
Open

How to mock static method in overlay type like JsDate.Create()? #41

AlexLuya opened this issue Sep 4, 2014 · 2 comments

Comments

@AlexLuya
Copy link

AlexLuya commented Sep 4, 2014

I have a class like this:

public class JsDateFake
{
public double getTime()
{
return JsDate.create().getTime();
}
}

Is it possible to mock this static method create() in gwtmockito?

@AlexLuya AlexLuya changed the title How to handle JsDate.Create()? How to mock static method in overlay type like JsDate.Create()? Sep 4, 2014
@ekuefler
Copy link
Collaborator

Yeah, mocking static methods (especially native ones) is always going to be difficult. I don't think this is something that can be done directly by Mockito or GwtMockito - if you want to make such code testable, you'll probably have to restructure your class slightly to take advantage of dependency injection, either manually or through Gin. For example, you could define a class like this:

class MyClass {
  private final Provider<JsDate> dateProvider;
  @UiField Label time;

  @Inject
  MyClass(Provider<JsDate> dateProvider) {
    this.dateProvider = dateProvider;
  }

  void updateTime() {
    time.setText("The time is " + dateProvider.get().getTime());
  }

With a provider method in a Gin module defined like this:

@Provide
JsDate provideJsDate() {
  return JsDate.create();
}

Then you could test your class like this:

@RunWith(GwtMockitoTestRunner.class)
public class MyClassTest {

  @Mock JsDate date;

  @Test
  public void testUpdateTime() {
    MyClass myClass = new MyClass(Providers.of(date));
    when(date.getTime()).thenReturn(1, 2);

    myClass.updateTime();
    myClass.updateTime();

    verify(myClass.time.setText("The time is 1"));
    verify(myClass.time.setText("The time is 2"));
  }
}

Would that work for you?

@schnatterer
Copy link

I experienced a similar issue with static methods in a smart GWT client, where I just couldn't see how to wrap the static method. So I build an (ugly?) extension for StubGenerator that helped me work around the issue.

Do you see an alternative to this approach, or would you extend GwtMockito with this functionality?

The problem is as follows

My workaround looks like this

public class StubGenerator {

    // ...

    /**
     * Allows to stub methods, even static ones. Use only if really necessary!
     * Try to use {@link Mockito#mock(Class)} instead!
     *
     * @param clazz the class to stub
     * @param method the method of <code>clazz</code> to stub
     * @param returnValue the value to be returned by <code>clazz.method</code>
     */
    public static void addStubbedMethod(Class<?> clazz, String method, final Object returnValue) {
        STUB_METHODS.put(new ClassAndMethod(clazz, method), new StubMethod() {
            @Override public Object invoke() {
                return returnValue;
            }
        });
    }

    // ...
}

In the test method calling

StubGenerator.addStubbedMethod(SC.class, "generateID", "a" + String.valueOf(System.currentTimeMillis()));

avoids the exception mentioned above.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants