Spring MVC Тест Mockito возвращает ошибку 406 вместо 200 - PullRequest
0 голосов
/ 01 августа 2020

Итак, я работаю с рабочим пользовательским интерфейсом и использую базу данных DB2. Я пытаюсь запустить модульное тестирование на уровнях контроллера / службы / дао, и я использую mockito и junit для тестирования. Вот части каждого слоя:

Measures.java

@Controller
@RequestMapping(value = "/measures"})
public class Measures {

    @Resource
    private CheckUpService checkUpService;
    
    public void setCheckUpService(CheckUpService checkUp) {
        this.checkUpService = checkUpService;
    }    

    @RequestMapping(value = "/eligibility/{userId}/{effDate}/{stageInd}", method = RequestMethod.POST, produces = "application/json")
    public @ResponseBody List<Model> findEligibility(@PathVariable int userId, @PathVariable String effDate, @PathVariable String stageInd) throws Exception
    {
        List<Model> result = new ArrayList<Model>();

        if (stageInd.equals("stage"))
        {
            result = checkUpService.findEligibilityStage(userId, effDate);
        }

        if (stageInd.equals("prod"))
        {
            result = checkUpService.findEligibility(userId, effDate);
        }

        return result;
    }
...
}

CheckUpService.java

public class CheckUpService {

    @Resource
    EligibilityDao eligDao;

    public List<Model> findEligibility(int userId, String effDate) throws Exception
        {
             return eligDao.findEligibility(userId, effDate, db_table);
        }
}

EligibilityDao.class

public class EligibilityDao {

    public List<Model> findEligibility(int userId, String effDate, String table) throws Exception
        {
            // uses some long sql statement to get some information db2 database and 
            // jdbctemplate helps return that into a list.
        }
}

Вот тест контроллера, который я пытаюсь провести, я потратил на это около 10 часов и действительно не могу понять, почему он дает мне ошибку 406 вместо 200.

ControllerTest.java

@EnableWebMvc
@WebAppConfiguration
public class ControllerTest {
    
    @Autowired
    private Measures measures;
    
    @Autowired
    private WebApplicationContext webApplicationContext;
    
    private MockMvc mockMvc;
    
    private List<Model> findEligibility() {
        
        List<Model> list = new ArrayList<>();
        
        Model test_model = new Model();
        
        test_model.setUserId(99);
        test_model.setCreateID("testUser");
        test_model.setEffDate("2020-07-30");
        
        list.add(test_model);
        
        return list;
    }
    
    @Before
    public void setup() throws Exception {
        this.mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
    }
    
    @Test
    public void test_find() throws Exception {
        
        CheckUpService checkUpService = mock(CheckUpService.class);
        
        when(checkUpService.findEligibility(99, "2020-07-30")).thenReturn(findEligibility());
        
        measures.setCheckUpService(checkUpService);
        
        String URI = "/measures/eligibility/99/2020-07-30/prod";
        
        MockHttpServletRequestBuilder requestBuilder = MockMvcRequestBuilders.post(URI).contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON);
        
        MvcResult handle = mockMvc.perform(requestBuilder).andReturn();

//      MvcResult handle = mockMvc.perform(requestBuilder).andExpect(status().isOk()).andReturn();

        MvcResult result = mockMvc.perform(asyncDispatch(handle)).andExpect(status().isOk()).andReturn();
        
//      assertThat(result.getResponse().getContentAsString()).isEqualTo(findEligibility()); 

    }
    
    
    
}

Результат MvcResult - это то, что выдает ошибку «StatusExpected <200>, но было <406>» в junit, и я схожу с ума, почему это так. Другая проблема заключается в том, что, если вы видите, я закомментировал дескриптор с помощью .andExpect (status (). IsOk ()), и этот дескриптор также вызывал ту же проблему. Я что-то неправильно настраиваю с тестом или что-то в этом роде?

1 Ответ

0 голосов
/ 01 августа 2020

Я не смог воспроизвести вашу проблему. Тем не менее, у меня это работает.

Итак, в Controller больших изменений нет, но я удалил инъекцию поля в пользу инъекции конструктора.

@Controller
@RequestMapping(value = "/measures")
public class Measures {

    private final CheckUpService checkUpService;

    public Measures(CheckUpService checkUpService) {
        this.checkUpService = checkUpService;
    }

    @RequestMapping(value = "/eligibility/{userId}/{effDate}/{stageInd}", method = RequestMethod.POST, produces = "application/json")
    public @ResponseBody List<Model> findEligibility(@PathVariable int userId, @PathVariable String effDate, @PathVariable String stageInd) throws Exception {
        List<Model> result = new ArrayList<>();

        if (stageInd.equals("stage")) {
            result = checkUpService.findEligibility(userId, effDate);
        }

        if (stageInd.equals("prod")) {
            result = checkUpService.findEligibility(userId, effDate);
        }

        return result;
    }
}

То же самое для службы class.

@Service
public class CheckUpService {

    private final EligibilityDao dao;

    public CheckUpService(EligibilityDao dao) {
        this.dao = dao;
    }

    public List<Model> findEligibility(int userId, String effDate) throws Exception {
        return dao.findEligibility(userId, effDate, "demo value");
    }
}

и вот тест. Вместо инициализации Mock Mvc и внедрения веб-контекста я ввожу Mock Mvc. Также, используя @MockBean, вы можете вводить mocks. Итак, я удалил создание макета из метода тестирования в часть инициализации.

@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
public class MeasuresTest {

    @Autowired
    private MockMvc mockMvc;

    @MockBean
    private CheckUpService service;

    @Test
    public void test_find() throws Exception {
        Model model = new Model(99, "2020-08-02", "2020-07-30");
        when(service.findEligibility(99, "2020-07-30"))
                .thenReturn(Collections.singletonList(model));
        String URI = "/measures/eligibility/99/2020-07-30/prod";

        MockHttpServletRequestBuilder requestBuilder = MockMvcRequestBuilders.post(URI)
                .contentType(MediaType.APPLICATION_JSON)
                .accept(MediaType.APPLICATION_JSON);

        final MvcResult mvcResult = mockMvc.perform(requestBuilder)
                .andExpect(status().isOk()).andReturn();

        final String json = mvcResult.getResponse().getContentAsString();

        final List<Model> models = new ObjectMapper().readValue(json, new TypeReference<>() {
        });

        Assert.assertEquals(1, models.size());
        Assert.assertEquals(model, models.get(0));
    }
}

В сообщении я не смог найти причину, по которой вы использовали asyncDispatch, поэтому я просто не использовал его.

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