Code to convert given time in UTC milliseconds to EST, irrespective of timezone of environment in which code executes.
Tuesday, December 07, 2010
Mockito: verify order of invocations
Sometimes there is need to verify the order of invocations happened on mock object. Take a look at below
Here, we want to verify that in ideal case
At first this test seems to be verifying what is suppose to, but unfortunately this test will not detect if
This is because
To make test verify invocation order, Mockito provides
If the order of invocation is changed in
Below is complete code.
RequestProcessor class. This class reads request from input stream, does some processing, write response to output stream and closes the connection. public class RequestProcessor {
private Socket socket;
public RequestProcessor(Socket socket) {
this.socket = socket;
}
public void process() {
try {
InputStream is = socket.getInputStream();
String response = processRequest(is);
PrintWriter pw = new PrintWriter(socket.getOutputStream());
pw.append(response);
pw.flush();
} catch (IOException e) {
// catch exception
} finally {
try {
socket.close();
} catch (IOException e) {}
}
}
private String processRequest(InputStream is) {
// process request and send response
}
}
Here, we want to verify that in ideal case
RequestProcessor should first read request from socket.getInputStream() and then after processing request, write response in socket.getOutputStream(). One way that comes in mind is to write test as:@Test public void socketClosedInIdealCase() throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ByteArrayInputStream bais = new ByteArrayInputStream("a=b+c".getBytes());
when(socketMock.getInputStream()).thenReturn(bais);
when(socketMock.getOutputStream()).thenReturn(baos);
RequestProcessor request = new RequestProcessor(socketMock);
request.process();
// verify method invocations
verify(socketMock).getInputStream();
verify(socketMock).getOutputStream();
}
At first this test seems to be verifying what is suppose to, but unfortunately this test will not detect if
socket.getOutputStream() is moved before socket.getInputStream() as done in below code.public void process() {
try {
OutputStream os = socket.getOutputStream()
InputStream is = socket.getInputStream();
String response = processRequest(is);
// rest of the code
} catch (IOException e) {
// catch exception
} finally {
try {
socket.close();
} catch (IOException e) {}
}
}
}
This is because
Mockito.verify() static method only verifies whether any invocation happened on mock object. It does not verifies order of invocation. To make test verify invocation order, Mockito provides
Mockito.inOrder static method. Using this method above test can be rewritten as:@Test public void socketClosedInIdealCase() throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ByteArrayInputStream bais = new ByteArrayInputStream("a=b+c".getBytes());
when(socketMock.getInputStream()).thenReturn(bais);
when(socketMock.getOutputStream()).thenReturn(baos);
RequestProcessor request = new RequestProcessor(socketMock);
request.process();
// verify method invocations
InOrder order = inOrder(socketMock);
order.verify(socketMock).getInputStream();
order.verify(socketMock).getOutputStream();
}
If the order of invocation is changed in
RequestProcessor.process() method, this test will fail.Below is complete code.
Thursday, December 02, 2010
Mockito: Two simple ways to create mock
Mockito is the simplest, cleanest and easiest to start with among other mocking frameworks present in java world. Being so simple, it still tries to make our test more cleaner and readable by providing two simple ways to create mocks depending upon the need. Let's look into those.
1. Using static
This is most common way to create mock. But what if mock is to be created and used in each test method in test class? One way to do is declare it as field and initialize it before test method is called. Something like this:
This looks simple and clean, but what if there are more than one field to be mocked? Create mock for each in
2. Using @Mock annotation
So when to use #1 and #2? As listed in java docs of
1. Using static
mock methodSocket socketMock = mock(Socket.class);
This is most common way to create mock. But what if mock is to be created and used in each test method in test class? One way to do is declare it as field and initialize it before test method is called. Something like this:
public class RequestProcessorTest {
private Socket socketMock;
@Before public void init() {
socketMock = mock(Socket.class);
}
}
This looks simple and clean, but what if there are more than one field to be mocked? Create mock for each in
init(). It's simple. But is there more simpler way to combine declaration and initialization process? Yes! that takes us to second point.2. Using @Mock annotation
@Mock annotation is shorthand for creating mock. This code shows how to create mocks using annotation.public class RequestProcessorTest {
@Mock private Socket socketMock;
@Before public void initMock() {
MockitoAnnotations.initMocks(this);
}
}
MockitoAnnotations.initMocks() is important here. It initializes all fields with @Mock annotation. In above code it creates mock of Socket and assigns it to socketMock. Using @Mock annotation has below listed advantages( as specified in mockito java docs): - Minimizes repetitive mock creation code.
- Makes the test class more readable.
- Makes the verification error easier to read because the field name is used to identify the mock.
So when to use #1 and #2? As listed in java docs of
@Mock annotation, if mock creation code is repetitive, I prefer to use #2 otherwise #1.
Wednesday, December 01, 2010
Why Ruby?
I don't completely agree with the presenter on monkey patching and Java, but was an interesting presentation.
Subscribe to:
Posts (Atom)