然后PowerMock测试通过失败

时间:2015-10-06 18:25:02

标签: java unit-testing mocking mockito powermock

为什么我的单元测试在独立运行时通过,但在运行多个测试时失败?

当我执行单个单元测试时,我的测试将成功模拟并返回预期结果。但是,当我运行所有单元测试时,我之前通过的测试将失败。

一次试运行

  

shouldDoThisAgain() - 传递

多次测试运行

  

shouldDoThis() - 传递

     

shouldDoThisAgain() - 失败

     

shouldDoThisAgainAgain() - 失败

我的测试:

@PrepareForTest({OtherMethods.class})
@PowerMockIgnore("javax.management.*")
@RunWith(PowerMockRunner.class)
public class DbTest {
    @Test
    public void shouldDoThis() throws Exception() {
        Dal dalMock = mock(Dal.class)
        PowerMockito.whenNew(Dal.class).withAnyArguments().thenReturn(dalMock)
        List<Result> results = new ArrayList<Result>();
        results.add(new Result(1,2,3));
        when(dalMock.getResults()).thenReturn(results)
        assertTrue(Wrapper.MY_WRAPPER.run()); 
    }
    @Test
    public void shouldDoThisAgain() throws Exception() {
        Dal dalMock = mock(Dal.class)
        PowerMockito.whenNew(Dal.class).withAnyArguments().thenReturn(dalMock)
        List<Result> results = new ArrayList<Result>();
        results.add(new Result(2,3,4));
        when(dalMock.getResults()).thenReturn(results)
        assertTrue(Wrapper.MY_WRAPPER.run());
    }
    @Test
    public void shouldDoThisAgainAgain() throws Exception() {
        Dal dalMock = mock(Dal.class)
        PowerMockito.whenNew(Dal.class).withAnyArguments().thenReturn(dalMock)
        List<Result> results = new ArrayList<Result>();
        results.add(new Result(6,5,3));
        when(dalMock.getResults()).thenReturn(results)
        assertTrue(Wrapper.MY_WRAPPER.run());
    }
}

我的课程:

public class Wrapper {
    // not Runnable
    public static final MyWrapper MY_WRAPPER = new MyWrapper(...){
        @Override
        public boolean run() {
           // returns empty list when the test is alone
           // returns 'results' variable when ran with other tests alone
           List<Result> results = OtherMethods.getDal().getResults();
           return !results.isEmpty()
        }
    };  
}

public class OtherMethods {
     private static final Logger LOGGER = LogManager.getLogger(OtherMethods.class);

     public static Dal dal;

     static Dal getDal() {
         if (dal == null) {
             try {   
                 dal = new Dal();
             } catch (Exception e) {
               LOGGER.fatal("DB Connection could not be created for Geonames");
               LOGGER.fatal(e);
           }
        }
        return dal;
    }
}

3 个答案:

答案 0 :(得分:6)

我找到了我们项目的解决方案。我写了一个调用Android内部静态Log方法的Logger类。我的一些测试没有直接测试Log类。当我忽略所有这些时,基于powermockito的测试变为绿色。但是当这些其他测试运行时,基于powermockito的测试将会失败。有时。

这种方法会失败(片状):

@RunWith(PowerMockRunner.class)
@PrepareForTest({Log.class})    // WARNING: HERE BE DRAGONS!
public class MyTest {

    @Test
    public void testMethodThatDoesNotUseStatics() {
        // ...
    }

    @Test
    public void usesStatics() {
        // ...
    }

}

然后我发现你可以使用@PrepareForTest注释每个测试方法,如下所示:

@RunWith(PowerMockRunner.class)
public class MyTest {

    @Test
    public void testMethodThatDoesNotUseStatics() {
        // ...
    }

    @Test
    @PrepareForTest({Log.class})    // that's the way :)
    public void usesStatics() {
        // ...
    }

}

现在测试再次变为绿色。是的非片状测试! :)

答案 1 :(得分:1)

检查@PrepareForTest({OtherMethods.class})在课堂级别时的行为......

已删除以回应OP的评论
我刚刚注意到其他事情:
我认为您的MyWrapper课程为Runnable,因此只能run()一次,您需要为每次测试重新初始化它 的删除

修改 那么你的问题出现在OtherMethods课程的实施中,你没有在这里展示,这让我们很难

答案 2 :(得分:0)

尝试这样做

@PrepareForTest({OtherMethods.class})
@PowerMockIgnore("javax.management.*")
@RunWith(MowerMockRunner.class)
public class DbTest {
@Before
public void setUp(){
     Dal dalMock = mock(Dal.class);        
PowerMockito.whenNew(Dal.class).withAnyArguments().thenReturn(dalMock);
List<Result> results = new ArrayList<Result>();
    results.add(new Result(1,2,3));
    when(OtherMethods.getDal().getResults()).thenReturn(results)
}
@Test
public void shouldDoThis() throws Exception() {

    assertTrue(Wrapper.MY_WRAPPER.run());
}
@Test
public void shouldDoThisAgain() throws Exception() {

    assertTrue(Wrapper.MY_WRAPPER.run());
}
@Test
public void shouldDoThisAgainAgain() throws Exception() {

    assertTrue(Wrapper.MY_WRAPPER.run());
}
}