模拟静态方法的替代方法
Alternatives to mock an static method
我正在开发桌面应用程序,我想测试 MyClass
的方法 foo
并且我有以下场景:
我的班级:
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);
但是MyClass
中没有设置MainWindow
,所以这也不是很有用。
最后我想出了一个解决方法来做我想要的,但它不是很干净。基本上我已经声明了一个静态布尔标志 printText
并在 MainWindow
的最开始将其设置为 false
,并且我在 class 构造函数中将其设置为 true。然后,在 printInMain
中,我仅在该标志为真时打印,只有在先前已实例化此 class 时才会发生。
这种方法可行,但我想知道是否有比这更好的解决方案,也许使用 Mockito 或其他一些模拟或测试技术,因为我对它们不是很熟悉。
我不认为这是一个很好的选择,因为我在应用程序中添加一些代码只是为了让测试工作,测试应该适应我的代码,而不是代码适应我的测试。
虽然在静态方法中放置空指针检查可以避免抛出 NPE;它有点代码味。
我建议将 jTextArea
声明为非静态的,这反过来意味着 printInMain
方法也将是非静态的。这导致它可以被嘲笑。
我正在开发桌面应用程序,我想测试 MyClass
的方法 foo
并且我有以下场景:
我的班级:
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);
但是MyClass
中没有设置MainWindow
,所以这也不是很有用。
最后我想出了一个解决方法来做我想要的,但它不是很干净。基本上我已经声明了一个静态布尔标志 printText
并在 MainWindow
的最开始将其设置为 false
,并且我在 class 构造函数中将其设置为 true。然后,在 printInMain
中,我仅在该标志为真时打印,只有在先前已实例化此 class 时才会发生。
这种方法可行,但我想知道是否有比这更好的解决方案,也许使用 Mockito 或其他一些模拟或测试技术,因为我对它们不是很熟悉。
我不认为这是一个很好的选择,因为我在应用程序中添加一些代码只是为了让测试工作,测试应该适应我的代码,而不是代码适应我的测试。
虽然在静态方法中放置空指针检查可以避免抛出 NPE;它有点代码味。
我建议将 jTextArea
声明为非静态的,这反过来意味着 printInMain
方法也将是非静态的。这导致它可以被嘲笑。