1

When I use run the follwoing code in my test class:

Mockito.when(accountHelper.convertAccountToJson(account)).thenReturn(jsonObject);

it is returning the jsonObject. However, in my AccountController, the follwoing code is returning null:

JSONObject accountJson = accountHelper.convertAccountToJson(account);

Can someone please explain why the mock response is not being reflected? Thanks in advance.

Here's is my code: TestClass

 @RunWith(MockitoJUnitRunner.class)
    public class AccountControllerTest {

        @InjectMocks private AccountController accountController;
        @Mock private AccountHelper accountHelper;

        MockMvc mockMvc;

        @Before
        public void setup() throws Exception {
            MockitoAnnotations.initMocks(this);
            mockMvc = MockMvcBuilders.standaloneSetup(accountController).build();
        }

        @Test
        public void createAccountEmptyMessage() throws Exception{
            String jsonString = "{}";
            String expectedReturnBody = "{\"name\":"test"}";

            Account account = new Account(test);
            JSONObject jsonObject = new JSONObject("{\"name\":"test"}");

            Mockito.when(accountHelper.convertAccountToJson(account)).thenReturn(jsonObject);

            mockMvc.perform(post("/createAccount").contentType(MediaType.APPLICATION_JSON).characterEncoding("UTF-8")
                    .accept(MediaType.APPLICATION_JSON).content(jsonString))
                    .andExpect(content().string(expectedReturnBody));
        }
    }

HelperClass

@Component
public class AccountHelper {
    public JSONObject convertAccountToJson(Account account) {
    String jsonString;
    JSONObject json;

    Gson gson = new Gson();

    try{
        jsonString = gson.toJson(account);
        json = new JSONObject(jsonString);
        logger.info(jsonString);
    } catch (Exception e) {
        return null;
    }

    return json;
}

Controller

@RestController
public class AccountController {
    @Autowired private AccountService accountService;
    @Autowired private AccountHelper accountHelper;

    @RequestMapping(method = RequestMethod.POST, value = "/createAccount")
    public ResponseEntity<Object> createAccount(@RequestBody(required= false) Account account) {
        try {
            JSONObject accountJson = accountHelper.convertAccountToJson(account); //Return null

            //Create Account

            return new ResponseEntity(accountJson.toString(), HttpStatus.OK);

        } catch (Exception e) {
            return new ResponseEntity(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }
}
SL07
  • 103
  • 1
  • 2
  • 15
  • It's hard to tell what's going on here. Can you format the code better? Separate the different classes into different blocks? – Christopher Schneider Feb 25 '17 at 00:22
  • You tell your mock to return this `jsonObject` when it receives `account`. So why should it return `null` like your real implementation? – QBrute Feb 25 '17 at 00:29
  • @ChristopherSchneider I've updated the question based on your request. – SL07 Feb 25 '17 at 00:36
  • @QBrute I've made a mistake by copying the wrong section of my code. I've updated the question. – SL07 Feb 25 '17 at 00:38
  • 1
    Mockito.when(accountHelper.convertAccountToJson(any())).thenReturn(jsonObject); can you replace the line with above and check ? Any() is from mockito pacakage. I am typing on the phone pardon my typos and formatting.. – harry Feb 25 '17 at 00:45
  • I'm admittedly ignorant on using `MockMvc`, but when you say `when(accountHelper.convertAccountToJson(account))` you're telling the mock to expect that _exact_ instance of `account`. Where is that instance getting passed to `createAccount`? There should be a `createAccount(account)` somewhere for that to work. – Christopher Schneider Feb 25 '17 at 00:46
  • @ChristopherSchneider My goal is to get that instance to pass to createAccount. – SL07 Feb 25 '17 at 00:49
  • @harry Your solution work. Why any() work in this case but not specifying a specific object? – SL07 Feb 25 '17 at 00:55
  • If you use `any()` you don't care what the actual object is. I would say that using `any()` ,while it makes your test pass, is a useless test in this instance. You should review [this answer](http://stackoverflow.com/questions/17972428/mock-mvc-add-request-parameter-to-test) to see how to actually pass in the `account` variable. Pay attention to the `.param()` method call. – Christopher Schneider Feb 25 '17 at 02:41
  • @ChristopherSchneider agreed my first approach would be to make that test case work with any and then you can use the matchers with mockito. If i recall correctly there is a argThat expression with mockito – harry Feb 26 '17 at 02:42
  • Yes !! Make that test work first then use custom matchers !!! With mockito @SL07 – harry Feb 26 '17 at 02:43
  • when(mockFoo.getBarByDouble(argThat(is(closeTo(1.0, 0.001))))). thenReturn(mockBar); something on the above lines – harry Feb 26 '17 at 02:48
  • http://stackoverflow.com/questions/8348046/mockitos-matcher-vs-hamcrest-matcher/8351055#8351055 – harry Feb 26 '17 at 02:49
  • 1
    I think i know where my issue is. The account in my AccountController is a RequestParam. For some reason, when I specify `Mockito.when(accountHelper.convertAccountToJson(account)).thenReturn(jsonObject);`, in my test class, the testing framework can't recognize that the account (in my test class) is the @RequestBody's account (in my controller). As a result, the mock is not being applied. Still trying to figure out how to fix this... – SL07 Feb 27 '17 at 17:59

0 Answers0