Reputation: 6073
I am using Spock and Mockito and am having a difficult time figuring out how to get value from Mocks.
I am attempting to build RESTful Services for a REST interface called UserResource
that communicate with an EJB3 Service layer.
The EJB3 Services will require new methods that are going to be written by another developer. Thus, I figured I would create a Mock in place of the REST interface.
Here is my Spock Test:
package commonapi.test
import commonapi.command.request.UserCreateRequest
import commonapi.command.resource.UserResource
import commonapi.response.CommandResponse
import org.mockito.Mock
import org.mockito.MockitoAnnotations
import spock.lang.Specification
import static org.mockito.BDDMockito.given
import static org.mockito.Mockito.*
/**
* Specification for Create User Command.
*/
class CreateUserTest extends Specification
{
/**
* Mocked Resource.
*/
@Mock
UserResource mockedUserResource;
def setup()
{
MockitoAnnotations.initMocks(this)
}
def "Mocked Resource Create Single User"()
{
given:
UserCreateRequest createRequest = new UserCreateRequest()
given(mockedUserResource.createUser(createRequest)).willReturn(new CommandResponse())
when:
CommandResponse commandResponse = mockedUserResource.createUser(createRequest)
then:
commandResponse != null
}
}
It compiles, and the test runs (passes)
Problem is, I feel like I'm not really "testing" anything. As far as I can understand, Mockito Mocks are simply "empty objects" where you can "set the behavior", i.e. given x, willReturn y.
However, if I am setting the behavior, I am essentially coding how they should behave for the purposes of that specific Spock Feature Method, which may or may not be the same for the real thing once it's implemented.
Basically I'm building up the behavior of the Mock for the purposes of a Test, and not testing the real thing.
I think I'm struggling a bit conceptually on how to leverage Mocks to test a System Under Development properly.
Any suggestions or insight would be greatly appreciated. Thank you in advance!
Upvotes: 3
Views: 1399
Reputation: 67380
Based off of the first part of your description, I think you're mocking the wrong thing. Let me reinterpret what you've said so you can see how I understand your problem:
In that case, you should be mocking out the EJB code, not your REST code. Here's an example in pure java/Mockito:
package com.sandbox;
import org.junit.Test;
import static org.mockito.Mockito.*;
public class SandboxTest {
@Test
public void myTest() {
Ejb mock = mock(Ejb.class);
RestApi restApi = new RestApi();
restApi.setEjb(mock);
restApi.doLogic();
verify(mock).logic();
}
private static class Ejb {
public void logic() {
}
}
private static class RestApi {
private Ejb ejb;
private void setEjb(Ejb ejb) {
this.ejb = ejb;
}
public void doLogic() {
ejb.logic();
}
}
}
Here the system under test is RestApi.doLogic
. And your tests should look somewhat similar to this. Notice I don't call the mock directly in my test. I call it indirectly by calling the System Under Test (RestApi.doLogic()
).
This is different from your example. All you're really testing is that you set up the mock correctly. To summarize, you should mock out the dependencies of the system under test, not the system under test.
Upvotes: 7