2017-07-05 1 views
0

J'essaye d'écrire un test pour mon contrôleur. Lorsque le service Web fonctionne, tout fonctionne correctement. Cependant, quand je lance le test que je reçois:Création de beans lors de l'auto-apprentissage avec Spring

Error creating bean with name 'Controller': Unsatisfied dependency expressed through field 'service'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.prov.Service' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

Comme vous pouvez le voir ci-dessous, je crois avoir tout correctement Autowired et ma structure de projet est correctement mis en place afin que le scanner de composants peut trouver les annotations correctement, Pourtant, j'ai toujours cette erreur.

Controller:

@RestController 
@RequestMapping("/api") 
public class Controller { 

    @Autowired 
    private Service service; 

    @JsonView(Views.All.class) 
    @RequestMapping(value = "/prov/users", method = RequestMethod.POST) 
    @ResponseBody 
    public CommonWebResponse<String> handleRequest(@RequestBody UserData userData) { 
     return service.prov(userData); 
    } 
} 

Service:

@Service 
public class Service { 

    @Autowired 
    private Repo repo; 

    @Autowired 
    private OtherService otherService; 

    public CommonWebResponse<String> prov(UserData userData) { 
     // do stuff here 
     return new SuccessWebResponse<>("Status"); 
    } 
} 

test Contrôleur:

@RunWith(SpringRunner.class) 
@WebMvcTest(
     controllers = Controller.class, 
     excludeFilters = { 
       @ComponentScan.Filter(
         type = FilterType.ASSIGNABLE_TYPE, 
         value = {CorsFilter.class, AuthenticationFilter.class} 
       ) 
     } 
) 
@AutoConfigureMockMvc(secure = false) 
public class ControllerTest { 

    public static final MediaType APPLICATION_JSON_UTF8 = new MediaType(MediaType.APPLICATION_JSON.getType(), MediaType.APPLICATION_JSON.getSubtype(), Charset.forName("utf8")); 

    @Autowired 
    private MockMvc mvc; 

    @Test 
    public void connectToEndpoint_shouldReturnTrue() { 
     UserData userData = new UserData("a", "bunch", "of", "fields"); 
     try { 
      mvc.perform(post("/api/prov/users").contentType(APPLICATION_JSON_UTF8) 
        .content(asJsonString(userData)) 
        .accept(MediaType.ALL)) 
        .andExpect(status().isOk()); 
     } catch (Exception e) { 
      Assert.fail(); 
     } 
    } 

} 

Répondre

1

La classe contrôleur autowires votre classe de service. Par conséquent, le test de la classe Controller requiert l'existence de votre classe Service, car Controller dépend de la création d'un bean de type Service. Cela signifie que vous devez soit @Autowired votre classe de service dans votre test, soit (de préférence) le simuler en utilisant quelque chose comme Mockito.

(modifier l'exemple de code):

@RunWith(SpringRunner.class) 
@WebMvcTest(Controller.class) 
public class ControllerTest { 
    @MockBean 
    private Service service 

    @Autowired 
    private MockMvc mvc; 

    @Test 
    public void foo() { 
     String somePayload = "Hello, World"; 
     String myParams = "foo"; 
     when(service.method(myParams)).thenReturn(somePayload); 
     mvc.perform(get("my/url/to/test").accept(MediaType.APPLICATION_JSON)) 
      .andExpect(status().isOk()) 
      .andExpect(jsonPath("$", is(equalTo("Hello, World")))); 
    } 
} 

Prenez note que cet exemple utilise Hamcrest pour des choses comme is() et equalTo()

+0

Merci, j'avais essayé de se moquer de service avant avec '@ MockBean' , mais je n'avais pas utilisé 'Mockito' pour se moquer de l'appel au service. La seule différence entre ma méthode finale et ce que vous avez fourni est que mes paramètres et charges utiles sont des objets de classe personnalisés et je n'utilise pas la dernière ligne: '.andExpect (jsonPath (" $ ", est (equalTo (" Bonjour, Monde ")))); 'puisque j'ai seulement besoin de montrer que l'extrémité est accessible. –

+1

J'ai ajouté ceux-ci juste pour montrer comment vous pourriez potentiellement vérifier les valeurs que le contrôleur retourne. Heureux d'aider! – SaxyPandaBear