Spring Boot Controller Test - Mockito, когда thenReturn список не работает - PullRequest
0 голосов
/ 03 марта 2020

Я издеваюсь над своим MemberServiceImpl классом. В частности, следующий метод getMembers(), который возвращает List<Golfer>:

@Service
public class MemberServiceImpl implements MemberService {

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    MemberRepository repository;

    @Override
    public List<Golfer> getMembers() {
        List<Golfer> members = repository.findAll();
        return members;
    }

В моем классе MemberControllerTest я создаю список игроков в гольф и использую когда thenReturn(members) перед отправкой моего запроса GET - который всегда возвращает пустой список. Есть идеи, что я делаю не так:

@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
class MemberControllerTest {

    @Mock
    MemberService memberService;

    @InjectMocks
    MemberController memberController = new MemberController();

    @Autowired
    private TestRestTemplate restTemplate;

    //bind RANDOM_PORT
    @LocalServerPort
    private int port;
    private String name = "David";
    private Golfer member = new Golfer("David");
    private HttpHeaders headers = new HttpHeaders();
    private String baseUrl = "http://localhost:";

    @Test
    void testGetAllMembers() throws Exception{
        restTemplate = new TestRestTemplate();
        HttpHeaders headers = new HttpHeaders();

        Golfer member1 = new Golfer("Harry");
        Golfer member2 = new Golfer("Maureen");
        List<Golfer> members = new ArrayList<Golfer>();
        members.add(member1);
        members.add(member2);

        when(memberService.getMembers()).thenReturn(members);

        ResponseEntity<List<Golfer>> response = restTemplate.exchange("http://localhost:"+port, HttpMethod.GET, null, new ParameterizedTypeReference<List<Golfer>>() {});

        assertEquals(members,response.getBody());
    }   
}

Ответы [ 2 ]

0 голосов
/ 07 марта 2020

Вы издеваетесь над объектом контроллера, но ожидаете, что он обработает запрос. Пусть Spring создаст контроллер, как при обычном запуске приложения, нет необходимости определять его самостоятельно.

Но вам нужно изменить определение MemberService на @MockBean, что означает, что когда Spring нуждается в Служба для внедрения в контроллер, который он создает, будет использовать этот фиктивный компонент:

@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
class MemberControllerTest {

    @MockBean
    MemberService memberService;

    @Autowired
    private TestRestTemplate restTemplate;

    //bind RANDOM_PORT
    @LocalServerPort
    private int port;
    private String name = "David";
    private Golfer member = new Golfer("David");
    private HttpHeaders headers = new HttpHeaders();
    private String baseUrl = "http://localhost:";

    @Test
    void testGetAllMembers() throws Exception{
        restTemplate = new TestRestTemplate();
        HttpHeaders headers = new HttpHeaders();

        Golfer member1 = new Golfer("Harry");
        Golfer member2 = new Golfer("Maureen");
        List<Golfer> members = new ArrayList<Golfer>();
        members.add(member1);
        members.add(member2);

        when(memberService.getMembers()).thenReturn(members);

        ResponseEntity<List<Golfer>> response = restTemplate.exchange("http://localhost:"+port, HttpMethod.GET, null, new ParameterizedTypeReference<List<Golfer>>() {});

        assertEquals(members,response.getBody());
    }
}
0 голосов
/ 03 марта 2020

Ваш макет не подобран контекстом приложения (теста). Таким образом, даже если вы имитируете свой сервис и внедряете его в экземпляр вашего контроллера в вашем тесте, этот экземпляр контроллера не является экземпляром, который будет использоваться контекстом приложения, когда вы запускаете запрос против вашего (тестового) приложения.

Вместо использования @Mock и @InjectMocks создайте класс TestConfiguration и используйте вместо него @MockBean для ServiceImpl. Удалите контроллер из теста все вместе, так как вам не нужно взаимодействовать с ним. Итак, что-то вроде:

@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) 
@Import(MemberControllerTestConfiguration.class)
class MemberControllerTest {

  @Autowired
  MemberService memberService;

  @Autowired
  private TestRestTemplate restTemplate;

//rest of your test

}


@TestConfiguration
class MemberControllerTestConfiguration{

  @MockBean
  MemberService memberService;
}

Я обычно склоняюсь к тому, чтобы сохранить эту конфигурацию теста внизу одного и того же файла теста, чтобы сохранить их вместе, поскольку это только то, что будет использоваться в этом тесте. Возможно, вам придется аннотировать помеченный компонент с помощью @Primary, если он начинает жаловаться на слишком много компонентов

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