davdic
davdic

Reputation: 249

Mockito when() not firing

I have the following structure:

List<MyObject> moList = new ArrayList<MyObject>();
processor.set(moList);    //This is initialized earlier

KeyValueStore<MyObject> moStore = mock(KeyValueStore.class);
when(moStore.add(eq(expectedKey), eq(mo))).thenThrow(new RuntimeException());

processor.setMoStore(moStore);
MyObject mo = new MyObject();
mo.setEmail("abc@123");
mo.setId("123");
moList.add(mo);

processor.process();

expectedKey = MyUtils.getHex("123_abc@123");       

ArgumentCaptor<String> strArg = ArgumentCaptor.forClass(String.class);
ArgumentCaptor<MyObject> moArg = ArgumentCaptor.forClass(MyObject.class);

verify(moStore).add(strArg.capture(), moArg.capture());

assertEquals(expectedKey, strArg.getValue());
assertEquals(mo, moArg.getValue());

Within the process, I call moStore.add() on the members of the moList with the derived expected key and the mo object. This is captured by the verify, and the assertEquals works. However, the when() does not fire and the exception (there for demonstration purposes, to make sure that I don't miss it) does not occur.

I am not sure what is going on here. The verify and the asserts pass, indicating that the add() was executed, but the when never fires. When I run the test it completes successfully, even though it should throw the exception.

EDIT:
I have changed my code to proposed structure where it is now as follows:

List<MyObject> moList = new ArrayList<MyObject>();
processor.set(moList);    //This is initialized earlier

KeyValueStore<MyObject> moStore = mock(KeyValueStore.class);

processor.setMoStore(moStore);
MyObject mo = new MyObject();
mo.setEmail("abc@123");
mo.setId("123");
moList.add(mo);

when(moStore.add(eq(expectedKey), eq(mo))).thenThrow(new RuntimeException());

processor.process();

expectedKey = MyUtils.getHex("123_abc@123");       

ArgumentCaptor<String> strArg = ArgumentCaptor.forClass(String.class);
ArgumentCaptor<MyObject> moArg = ArgumentCaptor.forClass(MyObject.class);

verify(moStore).add(strArg.capture(), moArg.capture());

assertEquals(expectedKey, strArg.getValue());
assertEquals(mo, moArg.getValue());

The problem remains: The assertEquals evaluate to true, but the when does not fire the RuntimeException. Even if I put the when after the process, or if I substitute when(moStore.add(anyString(), any(MyObject.class))).thenThrow(new RuntimeException()); the when does not fire.
How is the verify doing the verification correctly but the when is not firing? The two should give the same result, from what I know.

Upvotes: 0

Views: 185

Answers (1)

nhaarman
nhaarman

Reputation: 100388

when(moStore.add(eq(expectedKey), eq(mo))).thenThrow(new RuntimeException());

processor.setMoStore(moStore);
MyObject mo = new MyObject();
mo.setEmail("abc@123");
mo.setId("123");
moList.add(mo);

You say eq(mo), and then initialize mo to a new MyObject. The eq matcher has a wrong reference, and it will not match on your new MyObject.

Try initializing the mo object first, and then executing when.

Upvotes: 4

Related Questions