我需要测试的类看起来与此相似。我不是在这里写实际课程。
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");
我使测试案例工作。这是我所做的。
@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
}
您可以使createConnection
方法返回模拟连接。
首先,将方法更改为 protected
:
protected ConnectionImpl createConnection() {
.... // same code
}
如果该方法是私有的,则不能在测试中模拟它。
然后,在您的测试中,使用Mockito.spy
方法:
Client
对象进行间谍 @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或Maven或相似 - 包名称必须相同(
另一种做法是为连接制作设置方法:
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);
}