I'm trying to mock one function in an EntityListener, so the real implementation is not called in my test. The code looks like the following:
@EntityListeners(myEntityListener.class)
@Entity
public class myEntity {
...
}
public class myEntityListener {
public String doThis() {
// code i want to skip/mock
return expensiveToCompute;
}
@PrePersist
public void myListener(myEntity e) {
if (complexConditionToTest) e.setSomething(doThis());
}
}
I would like to mock doThis()
, but run the actual myListener()
function so I can test that the complex conditioning is correct.
I tried to test using Mockito, with the following code:
public class MyEntityListenerTest {
@Autowired
myEntityRepository repo;
@MockBean
myEntityListener entityListener;
@Test
public void myListenerTest() throws Exception {
String expected = "fake-text";
Mockito.when(entityListener.doThis()).thenReturn(expected);
myEntity e = new myEntity();
myEntity stored = repo.save(e);
assertThat(stored.getSomething()).isEqualTo(expected);
}
}
The myEntity constructor and doThis call both have more params, removed for simplicity in the example code.
I expected that this would mock the doThis function, but it does not appear to be mocked and the actual implemention is called instead. There are no error messages.
I am guessing that MockBean is not finding an existing myEntityListener bean and instead is creating a new one (which goes unused), but I am not sure how to make the test find the correct myEntityListener.
I couldn't get mockito to work, so I ended up creating a static field I could change instead:
@EntityListeners(MyEntityListener.class)
@Entity
public class myEntity {
...
}
public class MyEntityListener {
public static final testing = false;
public String doThis() {
if (testing) return "fake-text";
// code i want to skip/mock
return expensiveToCompute;
}
@PrePersist
public void myListener(myEntity e) {
if (complexConditionToTest) e.setSomething(doThis());
}
}
This makes the test look like:
public class MyEntityListenerTest {
@Autowired
myEntityRepository repo;
@Before
public final void setup() {
MyEntityListener.testing = true;
}
@Test
public void myListenerTest() throws Exception {
String expected = "fake-text";
myEntity e = new myEntity();
myEntity stored = repo.save(e);
assertThat(stored.getSomething()).isEqualTo(expected);
}
}
If you need the expected text to change you could probably use a string property instead of a boolean, but this was fine for my use case.