繁体   English   中英

Spring MVC Mockito 测试返回 406 错误而不是 200

[英]Spring MVC Mockito Test returning 406 error instead of 200

所以我正在使用一个工作用户界面,并使用一个 DB2 数据库。 我正在尝试在控制器/服务/dao 层上运行单元测试,并且我正在使用 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.
        }
}

这是我正在尝试做的 controller 测试,我在这上面花了大约 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 结果是在 junit 中引发“StatusExpected <200> 但为 <406>”错误的原因,我对它的原因感到很生气。 另一个问题是,如果你能看到,我用.andExpect(status().isOk()) 注释掉了句柄,并且那个也抛出了同样的问题。 是我在测试中设置错误还是什么?

我无法重现您的问题。 但是,我得到了这个工作。

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

这是测试。 我没有初始化 MockMvc 并注入 web 上下文,而是注入 MockMvc。 此外,使用@MockBean ,您可以注入模拟。 因此,我将模拟创建从测试方法移到了初始化部分。

@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的任何原因,所以我只是没有使用它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM