Как проверить уровень контроллера на подпружиненной загрузке с помощью сервиса autowiring? - PullRequest
0 голосов
/ 06 февраля 2020

Я пытаюсь проверить функциональность моего контроллера в моем API. Я реализовал следующий сервис под названием ExpertsServiceImpl.java:


@Service
@RequiredArgsConstructor
public class ExpertsServiceImpl implements ExpertsService{

    private final ExpertRepository repository;



    @Override
    public Experts createExpert(Experts expert) {
        return repository.save(expert);
    }
    @Override
    public void deleteExpert(ObjectId id) {
        Experts deleted = findExpertById(id);
        if(deleted == null) {
            throw new ExpertNotFoundException(id);
        }
        repository.delete(deleted);
    }
    public Experts findExpertById(ObjectId id) {
        Optional<Experts> searchedExpert = repository.findById(id);
        if(searchedExpert.get() == null) {
            throw new ExpertNotFoundException(id);
        }
        return searchedExpert.get();
    }

Это мой MongoDB репозиторий:

public interface ExpertRepository extends MongoRepository<Experts, ObjectId>{

}

И это мой класс контроллера:


@RestController
@Validated
class ExpertController {

    public final ExpertsService service;
    public ExpertController(ExpertsService service) {
        this.service = service;
    }


    @PostMapping(path = "/experts/",
              consumes = {MediaType.APPLICATION_JSON_VALUE},
              produces = {MediaType.APPLICATION_JSON_VALUE}
           )
    public Experts newExpert(@Valid @RequestBody Experts newExpert) {
        return service.createExpert(newExpert);


    }

    @DeleteMapping("/experts/{id}")
    public void deleteBook(@PathVariable  ObjectId id) throws Throwable {
        service.deleteExpert(id);
    }

Я пишу следующий тестовый класс для моего контроллера:

@ActiveProfiles("test")
@RunWith(SpringRunner.class)
@WebMvcTest(controllers = ExpertController.class)
class ExpertControllerTest {
    @Autowired
    private MockMvc mockMvc;

    @Autowired
    private ObjectMapper objectMapper;

    @Autowired
    private ExpertsService expertsService;

    @MockBean
    private ExpertRepository repository;

    Experts demoExpert = new Experts(ObjectId.get(),"Steve Jobs", "Enterpreneur",
                                     Availability.BUSY, Language.CHINESE);

    @Before
    public void setUp() throws Exception{
        expertsService.deleteAll();
        expertsService.createExpert(demoExpert);

    }

    @After
    public void tearDown() throws Exception{
        expertsService.deleteAll();
    }


    @Test
    public void deleteExpert() throws Exception {
        String expertId = demoExpert.getId();
        this.mockMvc.perform(MockMvcRequestBuilders
                .delete("/experts/{id}", expertId)
                .contentType(MediaType.APPLICATION_JSON)
                .accept(MediaType.APPLICATION_JSON))
                .andExpect(MockMvcResultMatchers.status().isOk());
    }

, который выдает эту ошибку:


java.lang.IllegalStateException: Failed to load ApplicationContext

    at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:132)
    at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:123)
    at org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener.postProcessFields(MockitoTestExecutionListener.java:95)
    at org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener.injectFields(MockitoTestExecutionListener.java:79)
    at org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener.prepareTestInstance(MockitoTestExecutionListener.java:54)
    at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:244)
    at org.springframework.test.context.junit.jupiter.SpringExtension.postProcessTestInstance(SpringExtension.java:98)
    at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeTestInstancePostProcessors$5(ClassBasedTestDescriptor.java:337)
    at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.executeAndMaskThrowable(ClassBasedTestDescriptor.java:342)
    at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeTestInstancePostProcessors$6(ClassBasedTestDescriptor.java:337)
    at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195)
    at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:177)
    at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1654)
    at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
    at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
    at java.base/java.util.stream.StreamSpliterators$WrappingSpliterator.forEachRemaining(StreamSpliterators.java:312)

Кто-нибудь понимает, как я мог это исправить? Я предполагаю, что это связано с тем, что я автоматически подключаю Службу и проверяю репозиторий, но не уверен, как это исправить. Я бы хотел, чтобы Служба была подключена автоматически, так как это не имело смысла для моих тестов. Кто-нибудь знает, как я мог go об этом? Я ценю любую помощь

Ответы [ 2 ]

0 голосов
/ 06 февраля 2020

если вы не хотите издеваться над сервисом, вы можете добавить @Import(ExpertsServiceImpl.class) поверх вашего тестового класса или использовать @SpringBootTest, как уже упоминалось (но в этом случае оно загрузит все приложение, что не очень хорошо). по производительности)

0 голосов
/ 06 февраля 2020

WebMvcTest только инициализирует слой Controller, поэтому все бины службы / репозитория не создаются и не внедряются. В вашем случае проблема заключается в

@Autowired
private ExpertsService expertsService;

Замените на

@MockBean
private ExpertsService expertsService;

Теперь у вас есть пробная версия для вашей службы, и вы можете сосредоточиться на тестировании только логика контроллера c.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...