使用Mockito/JUnit模拟Java常量变量(公共静态)

使用Mockito/JUnit模拟Java常量变量(公共静态),java,mockito,junit4,powermockito,Java,Mockito,Junit4,Powermockito,为了测试我的一个方法,我需要模拟常量变量。我怎么能和莫基托和朱尼特一起做呢 @Component( "mybean" ) @org.springframework.context.annotation.Scope( value="session" ) public class MyBean { Public void methodToBeTested() { if (!AppConst.SOME_CONST.equals(obj.getCostCode()

为了测试我的一个方法,我需要模拟常量变量。我怎么能和莫基托和朱尼特一起做呢

  @Component( "mybean" )
  @org.springframework.context.annotation.Scope( value="session" )  
  public class MyBean {

    Public void methodToBeTested() {
       if (!AppConst.SOME_CONST.equals(obj.getCostCode())) {
         // some logic
       }
    }
 }
AppConst类

@Configuration
public class AppConst
{
   public static  String  SOME_CONST;
   public static  String  HOST_URL;

   @PostConstruct
   public void postConstruct()
   {
     SOME_CONST = "My Code";
     HOST_URL  = "Some URL";

   }
}
那么,在我的junit测试类中,如何模拟AppConst及其变量呢?现在,当我运行它时,我遇到了一个空指针错误

这可以通过powermock实现吗?如果是,请提供一些样品

我使用的Mockito版本

编译“org.mockito:mockito all:1.9.5”

编译“org.powermock:powermock mockito release full:1.6.1”

代替mocking,还有另一个解决方案可以测试它:

public void methodToBeTested(SomeObject obj) {
   performLogic(AppConst.SOME_CONST, obj);
}

boolean performLogic(String check, SomeObject testObj) {
   if (!check.equals(obj.getCostCode())) {
     // some logic
     return true;
   }
   return false;
}
通过这种方式,您可以测试两件事,这两件事结合起来可以向您显示您的代码按预期工作:

public void testMethodToBeTested() {
    MyBean mb = new MyBean() {
        @Override
        void performLogic(String check, SomeObject testObj) {
            assertSame("check constant is passed", AppConst.SOME_CONST, check);
        }
    }
    mb.methodToBeTested(new SomeObject());

    mb = new MyBean();
    SomeObject so = createSomeTestObject("My Code"); // not the actual constant but an equal String
    assertFalse("check some logic not occurred", mb.performLogic("My Code", so));
    so = createSomeTestObject("Not the constant");
    assertFalse("check some logic not occurred", mb.performLogic("Not the constant", so));
    assertTrue("check some logic occurred", mb.performLogic("My Code", so));
    // additional tests covering the actual logic
}
另一种解决方案是将if语句的条件放入它自己的方法中,例如,
shouldlogiccurr(字符串检查)
,并单独测试该方法

换句话说:有时需要重构代码以使测试更容易,有时甚至完全可能。一个很好的副作用是,下一次实现某些东西时,您已经考虑到了可测试性,并首先创建了适合于此的代码


模拟是一种很好的方法,可以测试使用第三方库的东西,这些库无法更改,并且有太多的依赖项需要设置,但如果您最终将其用于自己的代码,则会出现设计问题。

如果您认为需要模拟这些库,那么您肯定是建模错误的。您应该将这些值注入到您的
MyBean
构造函数中(在现代Spring中,您应该通过
@ConfigurationProperties
配置它们)。@chrylis为什么需要注入它?它是一个静态变量,可以通过名称进行访问因为静态使你的代码成为一场噩梦;它们引入了隐藏耦合。常数很好,纯函数也很好。不是静态的。你是说为了使junit成功,我必须更改源代码?