web-dev-qa-db-fra.com

L'annotation MockBean dans le test Spring Boot provoque une exception NoUniqueBeanDefinitionException

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
6
JCN

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.

11
alexbt

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>
0
Snehal Masne