我正在调查哪个模拟框架用于我的项目,并将其缩小到JMockit和Mockito.
我注意到Mockito在Stackoverflow上被评为" Java最好的模拟框架 ".
在比较JMockit的" Mocking Tool Comparision Matrix "的功能时,似乎JMockit具有多种不同的功能.
有没有人有任何关于Mockito可以用JMockit无法实现的具体信息(不是意见),反之亦然?
我有一个Java方法,它使用ProcessBuilder启动一个Process,并将其输出传递给一个字节数组,然后在该过程结束时返回它的字节数组.
伪代码:
ProcessBuilder b = new ProcessBuilder("my.exe")
Process p = b.start();
... // get output from process, close process
Run Code Online (Sandbox Code Playgroud)
对这种方法进行单元测试的最佳方法是什么?我还没有找到一种方法来模拟ProcessBuilder(它是最终的),即使有令人难以置信的令人敬畏的JMockit,它也会给我一个NoClassDefFoundError:
java.lang.NoClassDefFoundError: test/MockProcessBuilder
at java.lang.ProcessBuilder.<init>(ProcessBuilder.java)
at mypackage.MyProcess.start(ReportReaderWrapperImpl.java:97)
at test.MyProcessTest.testStart(ReportReaderWrapperImplTest.java:28)
Run Code Online (Sandbox Code Playgroud)
有什么想法吗?
答案 - 正如奥拉夫所建议的那样,我最终将这些线重构为接口
Process start(String param) throws IOException;
Run Code Online (Sandbox Code Playgroud)
我现在将此接口的一个实例传递给我想要测试的类(在其构造函数中),通常使用带有原始行的默认实现.当我想测试时,我只需使用接口的模拟实现.像魅力一样,虽然我想知道我是否在这里过度接口......
这个问题不是关于OCP是什么.我也不是在寻找简单的答案.
所以,这就是我问这个的原因.OCP最初是在80年代后期描述的.它反映了当时的思想和背景.令人担忧的是,在代码已经过测试并投入生产之后,更改源代码以添加或修改功能将最终变得风险太大且成本高昂.因此,我们的想法是尽可能避免更改现有的源文件,并且只以子类(扩展)的形式添加到代码库中.
我可能错了,但我的印象是基于网络的版本控制系统(VCS)当时并未广泛使用.关键是VCS对于管理源代码更改至关重要.
重构的想法是最近的.那些支持自动重构操作的复杂IDE当然不存在.即使在今天,许多开发人员也没有使用最好的重构工具.这里的要点是,这样的现代工具允许开发人员在几秒钟内安全地改变数千行代码.
最后,今天,自动化开发人员测试(单元/集成测试)的想法很普遍.有许多免费和复杂的工具支持它.但是,如果我们从不/很少更改现有代码,那么创建和维护大型自动化测试套件有什么用?正如OCP所要求的那样,新代码只需要新的测试.
那么,OCP今天真的有意义吗?我不这么认为.相反,如果新功能不需要新类,我确实更愿意在添加新功能时更改现有代码.这样做可以使代码库更简单,更小,更易于阅读和理解.破坏以前功能的风险将通过VCS,重构工具和自动化测试套件进行管理.
嗨,我有一个方法,将URL作为输入,并确定它是否可访问.下面是代码:
public static boolean isUrlAccessible(final String urlToValidate) throws WAGNetworkException {
URL url = null;
HttpURLConnection huc = null;
int responseCode = -1;
try {
url = new URL(urlToValidate);
huc = (HttpURLConnection) url.openConnection();
huc.setRequestMethod("HEAD");
huc.connect();
responseCode = huc.getResponseCode();
} catch (final UnknownHostException e) {
throw new WAGNetworkException(WAGConstants.INTERNET_CONNECTION_EXCEPTION);
} catch (IOException e) {
throw new WAGNetworkException(WAGConstants.INVALID_URL_EXCEPTION);
} finally {
if (huc != null) {
huc.disconnect();
}
}
return responseCode == 200;
}
Run Code Online (Sandbox Code Playgroud)
我想使用isUrlAccessible()方法对单元进行单元测试PowerMockito.我觉得我需要用来whenNew()模拟创建URL和url.openConnection()调用的时候,返回另一个模拟HttpURLConnection …
说我有A级
class A {
final String foo() {
// .. computing result, contacting database, whatever ..
return "some computed value";
}
// ... and a bazillion other methods, some of them final.
}
Run Code Online (Sandbox Code Playgroud)
现在我有B级
class B {
String methodIWantToTest(A a) {
String output = a.foo();
// ... whatever this method does, e.g.:
output += "_suffix";
return output;
}
}
Run Code Online (Sandbox Code Playgroud)
我如何进行单元测试这种方法?原因foo()是final是因为我们不希望扩展A的类改变其功能.但同时要对方法进行真正的单元测试,我不希望它伸出并运行实际的A.foo()方法.
有没有办法,比如说,删除最终的关键字,并添加一个注释@finalUnlessTest?你会推荐什么?重构A到一个接口将是非常非常困难的,看它是如何它是我们的中心类之一,并且不幸的是非常非常耦合.
编辑#1抱歉,忘记提及,我们正在谈论Java.我们还没有使用模拟框架.
回答好的,所以:哇.JMockit是令人难以置信的,在我看来是测试遗留代码的杀手级应用程序.特别是在我的情况下,令人难以置信的有用.非常感谢!你基本上会为我的psuedo-example执行类似下面的操作:
class AMock {
final String …Run Code Online (Sandbox Code Playgroud) 我将使用此示例显示我的问题:
我有一个带有方法的类foo.该类有一个子类,它覆盖了这个方法.
子类'方法调用超类'方法.我可以验证吗?
我不想测试foo超类中的内容.我只需要验证它是否被调用.我知道重构可以帮助(有利于组合而不是继承等),但我无法做到这一点.
有没有办法达到我的需要?
以下是我尝试过的简单示例
package tmp;
import org.junit.Test;
import org.mockito.Mockito;
import static org.mockito.Mockito.times;
public class Example {
@Test
public void test() {
// given
ChildClass childClass = new ChildClass();
ChildClass spyChildClass = Mockito.spy(childClass);
// when
spyChildClass.foo(100);
// then
Mockito.verify((BaseClass) spyChildClass, times(1)).foo(101);
}
}
abstract class BaseClass {
public void foo(int n) {
System.out.printf("BaseClass.foo(%d)%n", n);
}
}
class ChildClass extends BaseClass {
@Override
public void foo(int n) {
System.out.printf("ChildClass.foo(%d)%n", n);
super.foo(n + 1); …Run Code Online (Sandbox Code Playgroud) 我无法模拟 Option 类。
我的伪代码是:
PowerMockito.when(stream.findAny()).thenReturn("Mock Of Optional class");
Run Code Online (Sandbox Code Playgroud)
但是每次运行此代码时 - 我都会收到Optional.empty.
我使用的是 1.5 版本的 PowerMock
...开放/封闭原则规定"软件实体(类,模块,功能等)应该是可以扩展的,但是关闭以进行修改"......这在生产环境中特别有价值,在这种环境中,源代码发生了变化可能需要代码审查,单元测试和其他此类程序才能使其符合产品使用要求:遵守原则的代码在扩展时不会发生变化,因此不需要这样的努力.
所以,我在正确的阅读它,如果有OCP将是有价值的无自动化单元测试,但不一定,如果有是?或维基百科的文章错了吗?
java ×6
jmockit ×4
mocking ×4
mockito ×3
unit-testing ×3
junit ×2
powermock ×2
inheritance ×1
legacy-code ×1