Tar*_*mar 37 java unit-testing mockito
我有一节课.
Class First {
private Second second;
public First(int num, String str) {
second = new Second(str);
this.num = num;
}
... // some other methods
}
Run Code Online (Sandbox Code Playgroud)
我想为First类的公共方法编写单元测试.我想避免执行类Second的构造函数.
我这样做了:
Second second = Mockito.mock(Second.class);
Mockito.when(new Second(any(String.class))).thenReturn(null);
First first = new First(null, null);
Run Code Online (Sandbox Code Playgroud)
它仍在调用类Second的构造函数.我怎么能避免呢?
小智 61
您可以使用PowerMockito
Second second = Mockito.mock(Second.class);
whenNew(Second.class).withNoArguments().thenReturn(second);
Run Code Online (Sandbox Code Playgroud)
但重新分解是更好的决定.
Tom*_*icz 25
单元测试的问题再次来自使用newoperator 手动创建对象.考虑传递已经创建的Second:
class First {
private Second second;
public First(int num, Second second) {
this.second = second;
this.num = num;
}
// some other methods...
}
Run Code Online (Sandbox Code Playgroud)
我知道这可能意味着重写你的API,但没有别的办法.这个班也没有任何意义:
Mockito.when(new Second(any(String.class).thenReturn(null)));
Run Code Online (Sandbox Code Playgroud)
首先,Mockito只能模拟方法,而不是构造函数.其次,即使你可以模拟构造函数,你也在嘲笑刚刚创建的对象的构造函数,而且从不真正对该对象做任何事情.
Roc*_*ena 14
以下是使用PowerMockito API模拟此功能的代码.
Second mockedSecond = PowerMockito.mock(Second.class);
PowerMockito.whenNew(Second.class).withNoArguments().thenReturn(mockedSecond);
Run Code Online (Sandbox Code Playgroud)
您需要使用Powermockito运行程序并需要添加所需的测试类(以逗号分隔),这些类需要由powermock API进行模拟.
@RunWith(PowerMockRunner.class)
@PrepareForTest({First.class,Second.class})
class TestClassName{
// your testing code
}
Run Code Online (Sandbox Code Playgroud)
Mockito 现在可以模拟构造函数(自版本 3.5.0 起)https://javadoc.io/static/org.mockito/mockito-core/3.5.13/org/mockito/Mockito.html#mocked_construction
try (MockedConstruction mocked = mockConstruction(Foo.class)) {
Foo foo = new Foo();
when(foo.method()).thenReturn("bar");
assertEquals("bar", foo.method());
verify(foo).method();
}
Run Code Online (Sandbox Code Playgroud)
小智 5
我使用过“模式 2 - “工厂助手模式”
模式 2 - 工厂助手模式
这种模式不起作用的一种情况是 MyClass 是最终的。大多数 Mockito 框架在 final 类中的表现并不是特别好;这包括使用 spy()。另一种情况是 MyClass 在某处使用 getClass(),并且要求结果值是 MyClass。这是行不通的,因为间谍的类实际上是原始类的 Mockito 生成的子类。
在这两种情况中的任何一种情况下,您都需要稍微更强大的工厂助手模式,如下所示。
Run Code Online (Sandbox Code Playgroud)public class MyClass{ static class FactoryHelper{ Foo makeFoo( A a, B b, C c ){ return new Foo( a, b, c ); } } //... private FactoryHelper helper; public MyClass( X x, Y y ){ this( x, y, new FactoryHelper()); } MyClass( X x, Y, y, FactoryHelper helper ){ //... this.helper = helper; } //... Foo foo = helper.makeFoo( a, b, c ); }所以,你有一个特殊的构造函数,只是为了测试,它有一个额外的参数。在创建要测试的对象时,它会从您的测试类中使用。在您的测试类中,您模拟 FactoryHelper 类以及您要创建的对象。
Run Code Online (Sandbox Code Playgroud)@Mock private MyClass.FactoryHelper mockFactoryHelper; @Mock private Foo mockFoo; private MyClass toTest;你可以像这样使用它
Run Code Online (Sandbox Code Playgroud)toTest = new MyClass( x, y, mockFactoryHelper ); when( mockFactoryHelper.makeFoo( any( A.class ), any( B.class ), any( C.class ))) .thenReturn( mockFoo );
来源:http : //web.archive.org/web/20160322155004/http : //code.google.com/p/mockito/wiki/MockingObjectCreation
| 归档时间: |
|
| 查看次数: |
118951 次 |
| 最近记录: |