不能使模拟单例的方法在不同的测试用例中表现不同

时间:2016-07-23 18:10:00

标签: java spring unit-testing singleton powermockito

类的单元测试涉及另一个类中的静态方法,比如HelperClassHelperClass有一个单身成员。我使用Junit进行单元测试,使用Powermockito来模拟单例成员。但我发现singleton成员方法的行为只能指定一次。

//the class to be tested
class Activity {
    public void enact() {
        //some logic
        String str = HelperClass.doSomething();
        //some other logic
    }
}

class HelperClass {
    private static final singleton = Singleton.getInstance();
    public static String doSomething() {
       //some logic
       AnObject obj;
       try {
           obj = singleton.doSomething();
       } catch (Exception1 e) {
           //Some other logic
           throw new Exception2("Some message" + e.getMessage(), e);
       }

       String val = obj.doSomething();
       return val;
    }
}

class Singleton {
    private Singleton instance = null;
    private void Singleton() { /*some logic*/ }
    public static Singleton getInstance() {
        if (instance == null) {
            Singleton();
        }
        return instance;
    }
    public String doSomething() throws Exception1 {
        //some logic
    }
}

我的uint测试就像这样

@RunWith(PowerMockRunner.class)
@PrepareForTest(Singleton.class)
class ActivityTest {
     //some logic
     private Activity activity;

     @Before
     public void setup() {
         //some logic
         PowerMockito.mockStatic(Singleton.class);
         activity = new Activity();
     }

     @Test(expected = Exception2.class)
     void test1() {
        Singleton mockSingleton = mock(Singleton.class);
        when(mockSingleton.doSomething()).thenThrow(new Exception1("Test Exception1"));
        PowerMockito.when(Singleton.getInstance()).thenReturn(mockSingleton);

        activity.enact();
     }

     @Test
     void test2() {
        Singleton mockSingleton = mock(Singleton.class);
        when(mockSingleton.doSomething()).thenReturn("");
        PowerMockito.when(Singleton.getInstance()).thenReturn(mockSingleton);

        activity.enact();
     }
}

但它不起作用。虽然我指定了doSomething()的{​​{1}}的不同行为,但mockSingleton仍然会mockSingleton中的Exception2test2中的test1一样。似乎行为只能指定一次。有人可以告诉我如何让这里doSomething()有不同的行为吗?

1 个答案:

答案 0 :(得分:1)

当您Signleton.getInstance初始化时,您只需拨打HelperClass一次。这样,您始终可以使用第一次测试中的模拟。要解决此问题,您可以在每次需要getInstance的实例时调用Singleton

因此,HelperClass的代码为:

class HelperClass {
    public static String doSomething() {
       //some logic
       AnObject obj;
       try {
           obj = Singleton.getInstance().doSomething();
       } catch (Exception1 e) {
           //Some other logic
           throw new Exception2("Some message" + e.getMessage(), e);
       }

       String val = obj.doSomething();
       return val;
    }
}

通过这种方式,您可以在每次运行中获得正确的模拟效果。