Reputation: 1253
I have a method in a service that I want to test and which uses MongoTemplate as follows:
@Service
public class MongoUpdateUtilityImpl implements MongoUpdateUtility {
private final MongoTemplate mongoTemplate;
@Autowired
MongoUpdateUtilityImpl (final MongoTemplate mongoTemplate) {
this.mongoTemplate = mongoTemplate;
}
@Override
public Object update(final String id, final Map<String, Object> fields, final Class<?> classType) {
...
this.mongoTemplate.updateFirst(query, update, classType);
return this.mongoTemplate.findById(id, classType);
}
}
Then I'm trying to test this method with mocked methods for mongo template:
@SpringBootTest
@RunWith(SpringJUnit4ClassRunner.class)
@ActiveProfiles("test")
public class MongoUpdateUtilityTest {
@MockBean
private MongoTemplate mongoTemplate;
@Autowired
private MongoUpdateUtility mongoUpdateUtility;
/**
* Test en el que se realiza una actualización correctamente.
*/
@Test
public void updateOK1() {
final Map<String, Object> map = new HashMap<>();
map.put("test", null);
map.put("test2", "value");
when(mongoTemplate.updateFirst(Mockito.any(Query.class), Mockito.any(Update.class), Mockito.any(Class.class)))
.thenReturn(null);
when(mongoTemplate.findById(Mockito.anyString(), Mockito.any(Class.class))).thenReturn(null);
assertNull(this.mongoUpdateUtility.update("2", map, Map.class));
}
}
I have read this question but when I try the answer marked as solution, it says that MongoTemplate cannot be initialized. I'd prefer to mock this than to use and embebded database since I'm limited on the libraries that I can use.
My error:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'operacionesPendientesRepository' defined in es.santander.gdopen.operpdtes.repository.OperacionesPendientesRepository defined in @EnableMongoRepositories declared on MongoRepositoriesRegistrar.EnableMongoRepositoriesConfiguration: Invocation of init method failed; nested exception is java.lang.NullPointerException
Upvotes: 5
Views: 10128
Reputation: 1555
If you don't need to process the "real" mongoTemplate (when you just need to test the business inside the method without real data persistence) you may use "deep mock" through the following config in Mockito:
@Mock(answer = Answers.RETURNS_MOCKS)
private MongoTemplate mongoTemplate
Then calls like these can be done (mocked) with no problem:
List<Entity> listResult = mongoTemplate.query(Entity.class)
.matching(query.with(Sort.by("anyField")))
.all();
This is specially usefull when you need to test code that uses third-part framework objects that cannot be "created" manually.
Upvotes: 1
Reputation: 25936
You are using @SpringBootTest which brings up entire application context. This means every bean defined in your app will be initialized.
This is an overkill for a test of a @Service:
For a test of a @Service, I advise you to take a simpler approach and test the service in isolation.
Upvotes: 7