如何在静态方法中对对象进行静态方法调用?

问题描述:

我是Junit测试的新手,但我必须测试一些代码。我想现在我知道它的基本功能,但我还是上了车,我不能在互联网上找到任何一个问题:如何在静态方法中对对象进行静态方法调用?

这里的课堂上,我想测试:

public static void methodToTest(Label l2, Label l3, User u) { 


    int first = MyDB.someMethod(u.anotherMethod()).size(); 
    int second = MyDB.someOtherMethod(u).size(); 


    if (first == 1) { 
     l2.setCaption("..."); 
    } 

    ... 
} 

我不要求系统创建整数'第一'和'第二'。相反,我只是希望它们是'1',所以我可以测试最后几行代码是否正常工作。

MYDB是一个公共类的静态方法(的someMethod()和someOtherMethod())

我要测试的方法methodToTest。我试图用parms调用这个方法,最后比较修改后的参数和预期的参数。

我使用Mockito和PowerMockito。

这是我的尝试之一:

@PrepareForTest({ClassToTest.class, MyDB.class }) 
@RunWith(PowerMockRunner.class) 
public class Test extends PowerMockTestCase{ 
    PowerMockito.mockStatic(MyDB.class); 
    PowerMockito.doReturn(1).when(MyDB.someMethod(u.anotherMethod()).size()); 
    PowerMockito.doReturn(1).when(MyDB.someOtherMethod(u).size()); 
    ClassToTest.methodToTest(l1, l2, u); 
    assertTrue(l1.equals(l3) && l2.equals(l4)); 
} 

,我得到的唯一的例外是: “参数传递给时()不是模仿!”

我希望任何人都可以帮助我。我花了很多时间来解决这个问题,但没有成功。

谢谢!!!

+0

当然,你可以嘲笑静态方法,但是摆脱它们以及它们带来的不便,隧道依赖不是更好吗?这是我的建议:避免静态方法。如果您正在使用其他人的代码,并且在进行测试之前不会对其进行重构,那么您可能会发现像JMockit这样的工具比Mockito和PowerMockito更易于使用。 – unigeek

正如我在我的评论中提到的,您已经发现静态方法是测试的障碍。所以,我建议你避免使用静态方法。让我们来看看这可能是什么样子在你的榜样:

你有一些代码,你需要测试..

public class ProductionClass { 
    public static void methodToTest(Label l2, Label l3, User u) { 
    int first = MyDB.someMethod(u.anotherMethod()).size(); 
    int second = MyDB.someOtherMethod(u).size(); 

    if (first == 1) { 
     l2.setCaption("..."); 
    } 

    ... 
    } 
} 

第一件事first..make生产类的静态方法的实例方法:

public class ProductionClass { 
    public void methodToTest(Label l2, Label l3, User u) { // removed "static" 
    int first = MyDB.someMethod(u.anotherMethod()).size(); 
    int second = MyDB.someOtherMethod(u).size(); 

    if (first == 1) { 
     l2.setCaption("..."); 
    } 

    ... 
    } 
} 

好吧,所以你仍然有耦合到MyDB的静态方法。摆脱这种静态方法只是让你的生产类更加可测试。这里是how..you可以这样做一对夫妇的提取方法的重构:

public class ProductionClass { 
    public void methodToTest(Label l2, Label l3, User u) { 
    int first = getFirst(); 
    int second = getSecond(); 

    if (first == 1) { 
     l2.setCaption("..."); 
    } 

    ... 
    } 

    int getFirst() { 
    return MyDB.someMethod(u.anotherMethod()).size(); 
    } 

    int getSecond() { 
    return MyDB.someOtherMethod(u).size(); 
    } 
} 

现在您可以轻松子类化生产类和覆盖(或部分模拟,如果您愿意),你要使用futz方法..

public class TestableProductionClass extends ProductionClass { 
    @Override 
    int getFirst() { 
    return 1; 
    } 

    @Override 
    int getSecond() { 
    return 1; 
    } 
} 

不会做出比任何更难它需要和引进PowerMock趋于增加复杂性,我宁愿不处理。因人而异。祝你好运!