Je ne parviens pas à utiliser l'annotation @MockBean. Les docs disent que MockBean peut remplacer un bean dans le contexte, mais je reçois une exception NoUniqueBeanDefinitionException dans mon test unitaire. Je ne vois pas comment utiliser l'annotation. Si je peux me moquer du référentiel, il y aura évidemment plus d'une définition de bean.
Je suis les exemples trouvés ici: https://spring.io/blog/2016/04/15/testing-improvements-in-spring-boot-1-4
J'ai un dépôt mongo:
public interface MyMongoRepository extends MongoRepository<MyDTO, String>
{
MyDTO findById(String id);
}
Et une ressource Jersey:
@Component
@Path("/createMatch")
public class Create
{
@Context
UriInfo uriInfo;
@Autowired
private MyMongoRepository repository;
@POST
@Produces(MediaType.APPLICATION_JSON)
public Response createMatch(@Context HttpServletResponse response)
{
MyDTO match = new MyDTO();
match = repository.save(match);
URI matchUri = uriInfo.getBaseUriBuilder().path(String.format("/%s/details", match.getId())).build();
return Response.created(matchUri)
.entity(new MyResponseEntity(Response.Status.CREATED, match, "Match created: " + matchUri))
.build();
}
}
Et un test JUnit:
@RunWith(SpringRunner.class)
@SpringBootTest
public class TestMocks {
@Autowired
private TestRestTemplate restTemplate;
@MockBean
private MyMongoRepository mockRepo;
@Before
public void setup()
{
MockitoAnnotations.initMocks(this);
given(this.mockRepo.findById("1234")).willReturn(
new MyDTO());
}
@Test
public void test()
{
this.restTemplate.getForEntity("/1234/details", MyResponseEntity.class);
}
}
Message d'erreur:
Field repository in path.to.my.resources.Create required a single bean, but 2 were found:
- myMongoRepository: defined in null
- path.to.my.MyMongoRepository#0: defined by method 'createMock' in null
C'est un bug: https://github.com/spring-projects/spring-boot/issues/6541
Le correctif se trouve dans spring-data 1.0.2-SNAPSHOT
et 2.0.3-SNAPSHOT
: https://github.com/arangodb/spring-data/issues/14#issuecomment-374141173
Si vous n'utilisez pas cette version, vous pouvez contourner ce problème en déclarant la maquette avec son nom:
@MockBean(name="myMongoRepository")
private MyMongoRepository repository;
En réponse à votre commentaire
De doc du printemps :
Pour plus de commodité, les tests qui doivent effectuer REST appels vers le serveur Démarré peuvent également @Autowire un TestRestTemplate qui Résoudra les liens relatifs au serveur en cours d'exécution.
En lisant cela, je pense que vous devez déclarer @SpringBootTest
dans un environnement Web:
@SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT)
Si votre démarrage printanier ne démarre pas l'environnement Web, quelle est la nécessité de TestRestTemplate
. Ainsi, je suppose que le printemps ne le rend même pas disponible.
Il suffit d'ajouter ci-dessous dans POM.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>