正如其他人所说,
readObject()
在
ObjectInputStream
中是
final
的。
我感谢其他人建议使用
PowerMock 来强制模拟这个类!
更好的解决方案是遵循 “针对接口编程” 模式。方法
readObject()
声明在
ObjectInput
接口中,由
ObjectInputStream
实现。因此,您可以更改类的签名,使用接口
ObjectInput
而不是具体类
ObjectInputStream
。
模拟接口
ObjectInput
很容易...
你能提供一个完整的示例吗?到目前为止,没有人这样做。 - Tobias Kolb
这就是它应该看起来的样子:
生产代码:
public class Person {
public Person(String string, String string2, String string3) {
}
}
class ClassUnderTest {
private final ObjectInput objectInput;
public ClassUnderTest(ObjectInput inputStream) {
objectInput = inputStream;
}
public Person readFromObjectStreamAsSideEffect() {
try {
return (Person) objectInput.readObject();
} catch (ClassNotFoundException | IOException e) {
throw new RuntimeException("some meaningful explanation.", e);
}
}
}
测试代码
@ExtendWith(MockitoExtension.class)
public class ConnectionTest {
@Mock
ObjectInput inputStream;
ClassUnderTest cut;
@BeforeEach
private void setup() {
cut = new ClassUnderTest(inputStream);
}
@Test
public void getPreparedObjectFromInputStreamy() throws Exception {
Person preparedValueObject = new Person("Doe", "John", "123");
when(inputStream.readObject()).thenReturn(preparedValueObject);
Person result = cut.readFromObjectStreamAsSideEffect();
assertEquals(preparedValueObject, result, "hint for reason of failing");
}
}
我的问题是关于writeObject()。具体来说,verify(serverInstance).ObjectOutPutStreamToClient.writeObject(someValue)
。你有没有一个好的解决方案?我认为这更难,因为writeObject
是void
。 - Tobias Kolb
不是我,而是Mockito有一个解决方案:
生产代码
public class Person {
public Person(String string, String string2, String string3) {
}
}
class ClassUnderTest {
private final ObjectOutput objectOutput;
public ClassUnderTest(ObjectOutput objectOutputStream) {
objectOutput = objectOutputStream;
}
public void writeObjects(List<Person> persons) {
try {
for (Person person : persons) {
objectOutput.writeObject(person);
}
} catch (IOException e) {
throw new RuntimeException("some meaningfull explanation.", e);
}
}
}
测试代码
@ExtendWith(MockitoExtension.class)
public class ConnectionTest {
@Mock
ObjectOutput outputStream;
ClassUnderTest cut;
@BeforeEach
private void setup() {
cut = new ClassUnderTest(outputStream);
}
@Test
public void getPreparedObjectFromInputStreamy() throws Exception {
List<Person> listToWrite = Arrays.asList(
new Person("Doe", "John", "123"),
new Person("Doe", "Jane", "456"));
cut.writeObjects(listToWrite);
ArgumentCaptor<Person> passedArgument = ArgumentCaptor.forClass(Person.class);
verify(outputStream, times(listToWrite.size())).writeObject(passedArgument.capture());
assertTrue(passedArgument.getAllValues().contains(listToWrite.get(0)), "hint for reason of failing");
assertTrue(passedArgument.getAllValues().contains(listToWrite.get(1)), "hint for reason of failing");
}
}