2017-07-05 3 views
0

Ich versuche, einen Test für meinen Controller zu schreiben. Wenn der Webservice läuft, funktioniert alles einwandfrei. Allerdings, wenn ich den Test ausführen, erhalte ich:Erstellen von Beans beim Autowirfen mit 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)}

Wie Sie unten sehen können, habe ich glaube, alles richtig Autowired und meine Projektstruktur richtig eingestellt ist, so dass die Komponente Scanner die Anmerkungen finden richtig, Trotzdem bekomme ich diesen Fehler immer noch.

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"); 
    } 
} 

Controller-Test:

@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(); 
     } 
    } 

} 

Antwort

1

Die Controller-Klasse autowires Service-Klasse. Daher erfordert das Testen der Controller-Klasse das Vorhandensein Ihrer Service-Klasse, da Controller davon abhängt, eine Bean vom Typ Service zu erstellen. Das heißt, Sie müssen entweder @Autowired Ihre Service-Klasse in Ihren Test, oder (vorzugsweise) mock es mit etwas wie Mockito.

(edit mit Codebeispiel):

@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")))); 
    } 
} 

Sie beachten, dass dieses Beispiel verwendet hamcrest für Dinge wie is() und equalTo()

+0

Danke, ich hatte versucht, den Dienst, bevor sie mit '@ MockBean' verspotten , aber ich hatte 'Mockito' nicht benutzt, um den eigentlichen Anruf beim Dienst zu verspotten. Der einzige Unterschied zwischen meiner endgültigen Methode und dem, was Sie zur Verfügung gestellt haben, ist, dass meine Params und Payload benutzerdefinierte Klassenobjekte sind und ich nicht die letzte Zeile verwende: '.andExpect (jsonPath (" $ ", is (equalTo (" Hello, World "))))); 'da ich nur zeigen muss, dass der Endpunkt zugänglich ist. –

+1

Ich fügte diese nur hinzu, um zu demonstrieren, wie Sie möglicherweise die Werte überprüfen können, die der Controller zurückgibt. Freue mich zu helfen! – SaxyPandaBear

Verwandte Themen