buttowski
buttowski

Reputation: 4907

Mock a static method

I want to write a test case that will verify a method in my class. I have a local ApplicationLauncher object in my method that has to be mocked because it calls a method, launch(), which should not be called in a unit test.

public class RunApp
{
   public void check(String name)
   {
     if(name !=null)
     {
       ApplicationLauncher launcher = Application.getLauncher("launch");
       String appName = name+".bat";
       launcher.launch(appName);
     }
   }
 }

My JUnit test code is below:

RunApp runapp = new RunApp();

@Mock
ApplicationLauncher launcher;

@Test
public void test()
{
  runapp.check("test");
  verify(launcher,atLeastOnce).launch(anyString());
}

I am not able to return a mock object like

when(Application.getLauncher(anyString())).thenReturn(launcher);

since getLauncher is a static method in Application class. How can I solve this?

Upvotes: 0

Views: 233

Answers (3)

Markus
Markus

Reputation: 819

You could refactor your class to accept the launcher to be "injected".

public class RunApp
{
  public void check(String name)
  {
    check(name, Application.getLauncher("launch"));
  }

  protected check(String name, ApplicationLauncher launcher) {
    if (name != null)
    {
      String appName = name + ".bat";
      launcher.launch(appName);
    }
  }
}

That way you could use the new package-protected check() method to test your code using a fake launcher.

Upvotes: 2

Duncan Jones
Duncan Jones

Reputation: 69329

A better application design might be to have ApplicationLauncher as an interface and create production and test implementations (or just mock the test implementation). You would need to pass an instance of ApplicationLauncher into your RunApp class, perhaps in the constructor.

Upvotes: 3

s106mo
s106mo

Reputation: 1253

You can mock static methods using PowerMock, however you should check whether the static method call is really necessary.

Upvotes: 2

Related Questions