我想测试此方法,但在方法内部创建一个新对象,然后调用该新对象的方法。我想跳过它(它涉及登录到我不感兴趣的j2ee服务器数据库)。作为一个简单的例子,我只想验证param1.logic()被调用一次,但测试最终失败,因为obj尝试使用我不想打扰输入的凭据登录。私有Object2 obj变量没有getter或setter,但有没有办法跳过构造函数并跟随logon调用?
public class Object1{
private Object2 obj;
public void method(Object3 param1, String param2){
//functionality
//logic to be tested
param1.logic();
//end functionality
//how can I skip these two lines?
obj = new Object2(param1);
obj.logon(param2,param2,null, false);
}
}
这是我尝试使用的内容,但仍在调用obj.logon中的方法。
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.powermock.api.mockito.PowerMockito;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
@RunWith(PowerMockRunner.class)
@PrepareForTest(Object2.class)
public class TestObject
{
@SuppressWarnings("unchecked")
@Before
public void init() throws Exception
{
var1 = mock(Object3.class)
obj2 = mock(Object2.class);
PowerMockito.whenNew(Object2.class).withAnyArguments().thenReturn(obj2);
}
@Test
public void testInvokeStandAloneJob() throws Exception
{
TestObject test = spy(new TestObject());
Mockito.doAnswer( new Answer<Object>(){
public Object answer(InvocationOnMock invocation){
Object[] args = invocation.getArguments();
return "called with arguments: " + args;
}
}).when(obj2).logon(Mockito.anyString(), Mockito.anyString(),Mockito.anyString(), Mockito.anyBoolean());
//also tried doNothing
//Mockito.doNothing().when(obj2).logon(sDomainName, username,null, false);
//call method
test.method(var1, var2);
verify(var1,times(1)).logic();
}
如何制作这两行(构造函数和以下方法什么都不做?)
答案 0 :(得分:1)
我相信你可以使用powermock来模拟对new()
的调用,并返回一个模拟对象,该对象在调用logon方法时什么都不做。
在使用PowerMock之前,请务必按照此页面上的说明操作:https://code.google.com/p/powermock/wiki/MockConstructor
具体做法是:
确保将其添加到测试类的顶部
@RunWith(PowerMockRunner.class)
@PrepareForTest(ClassThatCreatesTheNewInstance.class)
使用PowerMock.createMock(NewInstanceClass.class)创建应该构造的类的模拟对象(让我们称之为mockObject)。
或者,您可以重新设计您的课程,以便在该方法中不使用new
关键字。 (无论如何都是不好的做法)
答案 1 :(得分:0)
如果严格遵循依赖注入模式,模拟是测试的好方法。如果你不这样做,嘲笑就没那么大了。
您的行
obj = new Object2(param1);
违反了依赖注入。
您需要将其替换为
obj = object2Factory.create()
然后在构造函数中注入object2Factory或作为属性。
<强>更新强>
虽然我仍然不知道如何模拟原始代码,但我想制作另一种重构方法。
你可以重构行
obj = new Object2(param1);
obj.logon(param2,param2,null, false);
进入他们自己的package-private方法:
Object2 createObject2(Object3 param1, String param2) {
Object2 o = new Object2(param1);
o.logon(param2,param2,null, false);
return o;
}
然后,您可以使用spy()
来模拟createObject2()。