模拟静态方法的替代方法

时间:2015-05-04 10:14:51

标签: java junit static mocking mockito

我正在开发桌面应用程序,我想测试foo的方法MyClass,我有以下情况:
MyClass的:

import package.MainWindow;

public class MyClass{

    public int foo(){
        //some logic
        // . . .
        boolean result = getResult();
        if (result) {
            MainWindow.printInMain("Success");
            return 1;
        } else {
            MainWindow.printInMain("Fail: " + getCommentsAsString());
            return 2;
        }
    }
}

然后,我有MainWindow的静态方法printInMain

public class MainWindow{

    private static JTextArea jTextArea;

    MainWindow(){
        jTextArea = new JTextArea();
    }

    public static void printInMain(String string) {
        jTextArea.append(string + "\n");
        try {
           jTextArea.setCaretPosition(jTextArea.
             getLineStartOffset(jTextArea.getLineCount() - 1));
        } catch (BadLocationException e) {
            e.printStackTrace();
        }
    }
}

MainWindow是我程序的界面,jTextArea是打印我从MyClass.foo()发送的信息的swing组件。
现在我用jUnit测试foo(),我不需要图形用户界面来测试它。测试很简单,但是在调用打印方法时我得到一个nullPointer异常,因为MainWindow没有被实例化,所以jTextArea为空。
我的问题是,是否有任何干净的方法来避免抛出这个错误? 据我所知,我正在使用mockito,static methods cannot be mocked 在其他一些情况下,我本可以这样做:

MainWindow mainWindow = Mockito.mock(MainWindow.class);

MainWindow中没有设置MyClass,所以这也不是很有用 最后,我提出了一个可以满足我想要的解决方法,但它并不是很干净。基本上我已经声明了一个静态布尔标志printText并在false的最开始将其设置为MainWindow,我在类构造函数中将其设置为true。然后,在printInMain中,我只在这个标志为真时打印,这只有在此类先前被实例化时才会发生。 这种方法有效,但我想知道是否有比这更好的解决方案,可能使用Mockito或其他一些模拟或测试技术,因为我对它们不是很熟悉。
我不认为这是一个非常好的选择,因为我在应用程序中添加一些代码只是为了使测试工作,测试应该适应我的代码,而不是我的测试代码。

1 个答案:

答案 0 :(得分:1)

在静态方法中放入空指针检查会避免抛出NPE;它有点代码味道。

我建议将jTextArea声明为非静态,这反过来暗示printInMain方法也是非静态的。这导致它可以被嘲笑。