Java PowerMock测试通过,然后失败

Java PowerMock测试通过,然后失败,java,unit-testing,mocking,mockito,powermock,Java,Unit Testing,Mocking,Mockito,Powermock,为什么我的单元测试在独立运行时通过,但在运行多个测试时失败 当我执行单个单元测试时,我的测试将成功模拟并返回预期结果。然而,当我运行所有单元测试时,我以前通过的测试将失败 一次试运行 shouldDothis()-通过 多次测试运行 shoulddotthis()-通过 shouldDothisArea()-失败 shouldDoThisAgainAgain()-失败 我的测试: @PrepareForTest({OtherMethods.class}) @PowerMockIgnore(&qu

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

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

一次试运行

shouldDothis()-通过

多次测试运行

shoulddotthis()-通过

shouldDothisArea()-失败

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());
    }
}
@PrepareForTest({OtherMethods.class})
@PowerMockIgnore(“javax.management.*”)
@RunWith(PowerMockRunner.class)
公共类DbTest{
@试验
public void shoulddotthis()引发异常(){
Dal dalMock=mock(Dal.class)
PowerMockito.whenNew(Dal.class).withAnyArguments().thenReturn(dalMock)
列表结果=新建ArrayList();
结果。添加(新结果(1,2,3));
当(dalMock.getResults())。然后返回(results)
assertTrue(Wrapper.MY_Wrapper.run());
}
@试验
public void shoulddothisreach()引发异常(){
Dal dalMock=mock(Dal.class)
PowerMockito.whenNew(Dal.class).withAnyArguments().thenReturn(dalMock)
列表结果=新建ArrayList();
结果。添加(新结果(2,3,4));
当(dalMock.getResults())。然后返回(results)
assertTrue(Wrapper.MY_Wrapper.run());
}
@试验
public void shouldDoThisAgainAgain()引发异常(){
Dal dalMock=mock(Dal.class)
PowerMockito.whenNew(Dal.class).withAnyArguments().thenReturn(dalMock)
列表结果=新建ArrayList();
结果。添加(新结果(6,5,3));
当(dalMock.getResults())。然后返回(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;
    }
}
公共类包装器{
//无法运行
公共静态最终MyWrapper MY_WRAPPER=新MyWrapper(…){
@凌驾
公共布尔运行(){
//当测试单独进行时,返回空列表
//单独与其他测试一起运行时返回“results”变量
List results=OtherMethods.getDal().getResults();
return!results.isEmpty()
}
};  
}
公共类方法{
私有静态最终记录器Logger=LogManager.getLogger(OtherMethods.class);
公共静态Dal;
静态Dal getDal(){
如果(dal==null){
试试{
dal=新的dal();
}捕获(例外e){
LOGGER.fatal(“无法为Geonames创建DB连接”);
致命的(e);;
}
}
返回dal;
}
}

检查
@PrepareForTest({OtherMethods.class})
放置在类级别时的行为

针对OP的评论删除了
我注意到了另外一件事:
我假设您的
MyWrapper
类是
Runnable
,因此它只能
run()
一次,您需要为每个测试重新初始化它
已删除

编辑: 那么您的问题是在您的
其他方法的实现中
类,您没有在这里显示它,这使得我们很难尝试这样做

@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());
}
}
@PrepareForTest({OtherMethods.class})
@PowerMockIgnore(“javax.management.*”)
@RunWith(MowerMockRunner.class)
公共类DbTest{
@以前
公共作废设置(){
Dal-dalMock=mock(Dal.class);
PowerMockito.whenNew(Dal.class).withAnyArguments()。然后返回(dalMock);
列表结果=新建ArrayList();
结果。添加(新结果(1,2,3));
当(OtherMethods.getDal().getResults())。然后返回(results)
}
@试验
public void shoulddotthis()引发异常(){
assertTrue(Wrapper.MY_Wrapper.run());
}
@试验
public void shoulddothisreach()引发异常(){
assertTrue(Wrapper.MY_Wrapper.run());
}
@试验
public void shouldDoThisAgainAgain()引发异常(){
assertTrue(Wrapper.MY_Wrapper.run());
}
}

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

这种方法将失败(不可靠):

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

@RunWith(PowerMockRunner.class)
public class MyTest {

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

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

}

现在测试又是绿色的。对非片状测试来说是的!:)

对不起,它不能运行,我的错。我试图将它概括为一个可以执行的函数。你是对的,这是我对OtherMethods类的实现。嗯,差不多。我在原来的帖子中没有正确引用代码。我根据问题是如何发生的修改了它。基本上,我在我的
OtherMethods.class
中对我的dal做了一个单例模拟。然而,在我的测试中,我引用了本地
dalMock
对象,而不是RuleMethods中的mock对象。我的猜测是我指向了错误的对象。非常感谢。顺便说一句:当你发现有用的答案或评论时,标记/标记它们是很有用的……在我的“声誉”提高之前不能这么做。我做到了。它仍然复制相同的行为(假设我在每个@Test中更改
列表结果
)。您不必重复when(OtherMethods.getDal().getResults())。然后返回(results);每次更改结果时都要使用语句。只需使用.thenReturn(results1)、thenReturn(results2)等等。既然你在测试这个!在每种方法中,您都可以将这三个AssertTrue放在一个测试方法中。不需要三种不同的方法您实现的
其他方法
尤其是
getDal()
是一个非常糟糕的主意。Powermock+easymock+junit也有类似的情况。也只有第一次测试成功。在每次测试之前将{@PrepareForTest}移动到有帮助。但肖卢德一世
@RunWith(PowerMockRunner.class)
public class MyTest {

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

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

}