我需要测试的类看起来有点类似于此。我不是在这里写实际课程。
public class Client {
private String country;
private ConnectionImpl conn;
public Client (String country){
this.country = country;
}
private ConnectionImpl createConnection() {
SetConnectionImpl impl = new SetConnectionImpl() {
public String getFirstName() {
return "Some value";
}
public String getLastName() {
return "Some value";
}
public String getAddress() {
return "Some value";
}
public String getPhoneNumber() {
return "Some value";
}};
return new ConnectionImpl("", "", "", "", impl);
}
public String letsDoSomeWork(String requestObject) {
final ConnectionImpl impl = createConnection();
String letsHaveSomeResponse =
impl.methodTobeStubbed(requestObject);
return letsHaveSomeResponse;
}
}
现在我写的测试类看起来像这样。我正在使用mockito来编写存根。
@Runwith(MockitoJunitRunner.class)
public class ClientTest {
@Mock
ConnectionImpl impl;
private Client client;
@Before()
public void initialize() {
client = new Client("India");
}
@Test
public void testLetsDoSomework_ShouldReturnString() {
String request = "request";
when(impl.methodTobeStubbed(request)).thenReturn("Response");
String letsHaveSomeResponse = client.letsDoSomeWork(request);
//Now I will make Assertions
}
}
不幸的是,这个存根不起作用,我的假设是,因为要测试的类是在内部创建一个" impl"对象,我在这里创建的模拟对象没有被考虑。所以最后代码进入了" impl"不应该的课程。
when(impl.methodTobeStubbed(request)).thenReturn("Response");
答案 0 :(得分:0)
您可以让createConnection
方法返回您的模拟连接。
首先,将方法更改为protected
:
protected ConnectionImpl createConnection() {
.... // same code
}
如果该方法是私有的,则无法在测试中模拟它。
然后,在您的测试中,使用Client
方法使用Mockito.spy
对象进行间谍:
@Before()
public void initialize() {
client = Mockito.spy(new Client("India"));
// letsDoSomeWork method will be called (instead of a mocked version)
when(client.letsDoSomeWork(anyString())).thenCallRealMethod();
// createConnection returns your mocked impl object (it doesn't compile if createConnection method is private)
when(client.createConnection()).thenReturn(impl);
}
然后,当您致电letsDoSomeWork
时,它会调用Client
课程中的真实方法。因此,createConnection
将被调用 - 并且当它被模拟时,它将返回模拟的impl
对象。
注意:请确保ClientTest
类与Client
类位于同一个包中,以便通过测试使createConnection
可见(即使它们位于不同的源文件夹中 - 比如src/main
和src/test
,假设您正在使用maven或类似名称 - 包名称必须相同)
另一种方法是为连接创建一个setter方法:
public class Client {
private String country;
private ConnectionImpl conn;
public Client(String country) {
this.country = country;
}
// create setter method for connection
public void setConn(ConnectionImpl conn) {
this.conn = conn;
}
public String letsDoSomeWork(String requestObject) {
// no need to createConnection
String letsHaveSomeResponse =
this.conn.methodTobeStubbed(requestObject);
return letsHaveSomeResponse;
}
}
所以你的测试就像:
@RunWith(MockitoJUnitRunner.class)
public class ClientTest {
@Mock
MyConn impl;
private Client client;
@Before
public void initialize() {
client = new Client("India");
client.setConn(impl);
}
@Test
public void testLetsDoSomework_ShouldReturnString() {
String request = "request";
when(impl.methodTobeStubbed(request)).thenReturn("Response");
String letsHaveSomeResponse = client.letsDoSomeWork(request);
// do assertions
}
}
甚至更好,制作一个接收连接的构造函数:
public Client(String country, ConnectionImpl conn) {
this.country = country;
this.conn = conn;
}
在测试课程中:
@Before
public void initialize() {
client = new Client("India", impl);
}
答案 1 :(得分:0)
我让测试用例发挥作用。这就是我所做的。
@RunWith(PowerMockRunner.class)
@PrepareForTest(Client.class)
public class ClientTest {
@Mock
ConnectionImpl impl;
private Client client;
@Before()
public void initialize() {
client = PowerMockito.spy(new Client("India"));
doReturn(impl).when(client, "createConnection");
}
@Test
public void testLetsDoSomework_ShouldReturnString() {
String request = "request";
when(impl.methodTobeStubbed(request)).thenReturn("Response");
String letsHaveSomeResponse = client.letsDoSomeWork(request);
//Now I will make Assertions
}