1

I've started playing around with mockito today and I've encountered a problem. This is the class I'm trying to create test cases on:

@Path("search")
public class SearchWebService {

private static final Logger logger = Logger.getLogger(SearchWebService.class);

@EJB
UserServiceInterface userService;

@GET
@Path("/json/{searchstring}")
@Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
@RolesAllowed("User")
public List getJSONFromSearchResults(@PathParam("searchstring") String searchString, @Context HttpServletRequest request) {
    logger.info("getJSONFromSearchResults called");

    //Users own email
    String ownemail = request.getRemoteUser();

    if (searchString.contains(" ")) {
        //Split String in two at first space
        String names[] = searchString.split("\\s+", 2);

        List userList = userService.searchByFullName(names[0], names[1], ownemail);
        if (userList.size() > 0) {
            return userList;
        } //Check for cases where the last name contains spaces
        else {
            return userService.searchByLastName(searchString, ownemail);
        }
    }
    return userService.searchBySingleName(searchString, ownemail);
}
}

I'm at searchString.contains(" ") and I'm trying to invoke "when(...).thenReturn(...)" But mockito throws an exception saying that "Cannot mock/spy class java.lang.String" I'm not sure I'm doing it correctly when testing this web service. Maybe there is some otherway to do this? Here is my test class:

public class SearchWebServiceTest {

@Mock
UserServiceInterface mockedUserService;
@Mock
Logger mockedLogger;
@Mock
HttpServletRequest mockedRequest;
@Mock
String mockedString;
@Mock
List<SearchResultsContainer> mockedUserList;

@Before
public void setUp() throws Exception {
    MockitoAnnotations.initMocks(this);
}

@Test
public void testGetJSONFromSearchResultsSpace() throws Exception {
    when(mockedRequest.getRemoteUser()).thenReturn("email");
    when("StringWithSpace".contains(" ")).thenReturn(true);
    when("StringWitchSpace".split("\\s+", 2)).thenReturn(null);
    when(mockedUserService.searchByFullName("name1", "name2", "email")).thenReturn(mockedUserList);
    assertTrue(mockedUserList.size() > 0);
}
Sam Gholizadeh
  • 217
  • 2
  • 3
  • 10
  • are you trying to mock the operation of .contains() ? – Aritra Sep 18 '14 at 14:33
  • Yes tried to mock a String object and now a string directly in the when method. Does not work. I'm new to testing as well so Maybe there is already a specific way to mock String methods. – Sam Gholizadeh Sep 18 '14 at 14:37
  • what are you trying to test exactly? – Aritra Sep 18 '14 at 14:41
  • Try using JMockit. You can mock up final classes there. – Evdzhan Mustafa Sep 18 '14 at 14:46
  • 3
    To me, it seems there's a problem in the understanding of the use of a mocking framework. Your assertion is on a mocked object. Mocking is done to mock unwanted dependencies, and test some real code. See: http://stackoverflow.com/questions/2665812/what-is-mocking – Aritra Sep 18 '14 at 14:51
  • possible duplicate of [Mockito Verification Not Failing](http://stackoverflow.com/questions/9553606/mockito-verification-not-failing) –  Sep 18 '14 at 15:35
  • 3
    please pay attention to @Aritra and her comments. You should never have to mock a Java String under any circumstances -- ever. Just use a real string. – Kevin Welker Sep 18 '14 at 15:42

3 Answers3

5

you cannot mock final classes (like String). This is a known limitation of the framework.

You can refer this link.

Mockito Verification Not Failing

I hope it helps !!!

Community
  • 1
  • 1
DeepInJava
  • 1,871
  • 3
  • 16
  • 31
1

If you need to invoke your service with a String that has a space, then just pass it a string that has a space. And don't mock the class that you are trying to test. You should mock as little as possible in unit tests. Simply provide real input data that meets the particular conditions of your particular test. Only mock collaborators, and only when you need to. If you need a String (either as a parameter or as a return value of a collaborator) that meets certain conditions, then just provide such an example String.

Kevin Welker
  • 7,719
  • 1
  • 40
  • 56
0

so if you need to test some method on string then best way is use reflection method to assign value to your string variable. I used apache common library for it

FieldUtils.writeField(yourClass, "variableName", "value", true);