【问题标题】:Despite having `when()` method it returns null尽管有`when()`方法它返回null
【发布时间】:2019-09-10 13:17:54
【问题描述】:

我想测试控制器方法是否返回http status 200

@Slf4j
@Controller
public class AcknowledgeAlertsServiceImpl implements AcknowledgeAlertsService {

    ...

    @Override
    @RequestMapping(value = SERVICE_MAPPING, method = POST)
    public @ResponseBody
    ResponseEntity acknowledge(@PathVariable(ALERT_ID) String alertId) {

        ....

        try {
            Map.Entry<AlertID, AlertJTO> entry = cache.findUserEntryById(alertId, userLogin);
            ...
            return new ResponseEntity(HttpStatus.OK);
        } catch (Exception ex) {
            ...
            return new ResponseEntity(HttpStatus.BAD_REQUEST);
        }
    }
}

我已经模拟了缓存并添加了when(),它将findUserEntryById 设置为返回给定的条目。不幸的是,它返回一个空值,不知道为什么,稍后会抛出空值并捕获“捕获”。问题是为什么它返回 null 尽管设置了它应该返回的行为。 结果是 http 代码 400,而不是 200。我想正确传递所有内容,无论传递什么。

public Map.Entry<AlertID, AlertJTO> findUserEntryById(String alertId, String userLogin) {
        return cache.entrySet()
                .stream()
                .filter(key -> key.getKey()
                        .getUserLogin()
                        .equals(userLogin))
                .filter(entry -> entry.getValue()
                        .getId()
                        .equals(alertId))
                .findFirst()
                .orElse(null);
    }

测试:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "..." })
@WebAppConfiguration
 public class AcknowledgeAlertsServiceImplTest {

private static final String ALERT_ID = "123";

...

private MockMvc mockMvc;

...
   ...


 @Test
public void acknowledgeOfExistingAlert() throws Exception {
    //given
    UserData userData = mock(UserData.class);
    AlertID alertID = mock(AlertID.class);
    AlertJTO alertJTO = mock(AlertJTO.class);

    Map.Entry<AlertID, AlertJTO> entry = new AbstractMap.SimpleEntry<>(alertID, alertJTO);
    //when
    when(flightmapUserContext.getUserData()).thenReturn(userData);
    when(cache.findUserEntryById(any(),any())).thenReturn(entry);
    //then
    mockMvc.perform(MockMvcRequestBuilders.post(url(), ALERT_ID)
            .param(AcknowledgeAlertsService.ALERT_ID, ALERT_ID))
            .andExpect(MockMvcResultMatchers.status()
                    .isOk());
}

【问题讨论】:

  • 从您提供的代码中,尚不清楚 userLogin 在实际代码中的来源。是否等于“何时”的“登录”?
  • 同样,我没有看到任何会返回“登录”的模拟,您只在调用 when(alertsCache.findUserEntryById("123", "login")).thenReturn(entry); 时显示它使用。只需调试 `Map.Entry entry = alertsCache.findUserEntryById(alertId, userLogin);` 并确保 userLogin == "login"
  • 另一种选择是将when(alertsCache.findUserEntryById("123", "login")) 替换为when(alertsCache.findUserEntryById(any(), any())) - 如果可行,则值不同

标签: java junit mockito mockmvc


【解决方案1】:

我觉得你不见了

@InjectMocks
    FlightAcknowledgeAlertsServiceImpl controllerUnderTest;

所以控制器实例不会得到模拟。

【讨论】:

    【解决方案2】:

    看看 Spring 的 @MockBean 注释。删除 @InjectMocks 并留下:

    @RunWith(SpringRunner.class)
    @WebMvcTest(SomeController.class)
    public class SomeControllerIT {
    
      @MockBean
      private AlertsCache alertsCache;
    
      @Autowired
      private MockMvc mockMvc;
    
      @Before
      public void setUp() {
        when(alertsCache.findUserById(anyLong())).thenReturn(someEntry);
      }
    }
    

    然后做正常的 when/thenReturn 事情。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-11-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多