测试私有静态方法

时间:2014-10-31 15:45:37

标签: java unit-testing mocking static-methods jmockit

您好我想测试generateKey方法和Dispatcher调度的消息。我试图模拟类和公共方法verifyOtherDetails()。在其中我创建了一个期望,即调度程序方法具有文字值,但它总是通过。任何帮助将不胜感激。

请参阅底部我的尝试代码谢谢。

abstract class KeyGen {

  private static void generateKey(String key, String username){
    if(Strings.isNullOrEmpty(key)){
      Dispatcher.dispatch(new WarningString(String.format("The key is null or empty for user %s", username)));
    }else{
      Dispatcher.dispatch(new InfoString(String.format("The key is correct for user %s", username)));
    }
  }

  public void verifyOtherDetails(String address, Map<String, String> favouriteFilms){
    String key ="";
    String username ="";
    generateKey(key, username);
  }
}

public class TestKeyGen {

  @Test
  public void testKey() {
    new MockUp<KeyGen>() {
      @Mock()
      public void verifyOtherDetails() {

        String key = "sfjhlkjhfkjdhlsk";
        final String username = "Daniel";
        new Expectations() {
          {
            Dispatcher.dispatch(new WarningString(String.format("The key is null or empty for user %s", username)));
          }
        };
      }
    };
  }
}

2 个答案:

答案 0 :(得分:2)

鉴于你的设计,我说它很难测试你的方法。基本上这是因为你使用调度程序类的静态方法,所以你不能轻易地模拟它。

你有一个选择的轿跑车。您可以在测试中订阅调度程序消息,并检查预期的消息是否到达。这是侵入性最小的,并且可以作为集成测试。

另一个选项是在接口中包装调度程序静态调用,并将此接口的模拟注入到KeyGen类中,然后通过公共方法测试接口上的方法是否被调用。

public interface DispatchWrapper{
    void dispatch(IString stringToDispatch);
}

public class StaticDispatcher : DispatchWrapper{
    void dispatch(IString stringToDispatch)
    {
            Dispatcher.dispatch(stringToDispatch);
    }
}

abstract class KeyGen {
  private DispatchWrapper wrapper;

  public KeyGen(DispatchWrapper wrapper){
      this.wrapper = wrapper;
  }
  private static void generateKey(String key, String username){
    if(Strings.isNullOrEmpty(key)){
      wrapper.dispatch(new WarningString(String.format("The key is null or empty for user %s", username)));
    }else{
      wrapper.dispatch(new InfoString(String.format("The key is correct for user %s", username)));
    }
  }

  public void verifyOtherDetails(String address, Map<String, String> favouriteFilms){
    String key ="";
    String username ="";
    generateKey(key, username);
  }
}

第三个选项是将私有方法移动到另一个静态类并将其公开,然后您可以测试该类(与静态调度程序具有相同的问题)。然后,KeyGen类可以成为VerifyingKeyGen,只需验证然后委托其他方法实际生成密钥。这很好地区分了你所拥有的两个问题,即生成新密钥和验证deatils

public static class KeyGen {

  public static void generateKey(String key, String username){
    if(Strings.isNullOrEmpty(key)){
      Dispatcher.dispatch(new WarningString(String.format("The key is null or empty for user %s", username)));
    }else{
      Dispatcher.dispatch(new InfoString(String.format("The key is correct for user %s", username)));
    }
  }

abstract class VerifyingKeyGen{

  public void verifyOtherDetails(String address, Map<String, String> favouriteFilms){
    String key ="";
    String username ="";
    KeyGen.generateKey(key, username);
  }
}

答案 1 :(得分:1)

问题中的测试修正版本:

@Tested KeyGen keyGen;
@Mocked Dispatcher dispatcher;

@Test
public void testKey() {
    keyGen.verifyOtherDetails("???", null);

    final WarningString warning = 
        new WarningString("The key is null or empty for user ");

    new Verifications() {{ Dispatcher.dispatch(warning); }};
}

(前提是WarningString实现了equals方法。)