@Test
public void testUpdateFlowRule() throws Exception {

    String path = "/gateway/flow/save.json";
    // Add one entity into memory repository for update
    GatewayFlowRuleEntity addEntity = new GatewayFlowRuleEntity();
    addEntity.setId(1L);
    addEntity.setApp(TEST_APP);
    addEntity.setIp(TEST_IP);
    addEntity.setPort(TEST_PORT);
    addEntity.setResource("httpbin_route");
    addEntity.setResourceMode(RESOURCE_MODE_ROUTE_ID);
    addEntity.setGrade(FLOW_GRADE_QPS);
    addEntity.setCount(5D);
    addEntity.setInterval(30L);
    addEntity.setIntervalUnit(GatewayFlowRuleEntity.INTERVAL_UNIT_SECOND);
    addEntity.setControlBehavior(CONTROL_BEHAVIOR_DEFAULT);
    addEntity.setBurst(0);
    addEntity.setMaxQueueingTimeoutMs(0);
    Date date = new Date();
    // To make the gmtModified different when do update
    date = DateUtils.addSeconds(date, -1);
    addEntity.setGmtCreate(date);
    addEntity.setGmtModified(date);
    GatewayParamFlowItemEntity addItemEntity = new GatewayParamFlowItemEntity();
    addEntity.setParamItem(addItemEntity);
    addItemEntity.setParseStrategy(PARAM_PARSE_STRATEGY_CLIENT_IP);
    repository.save(addEntity);
    UpdateFlowRuleReqVo reqVo = new UpdateFlowRuleReqVo();
    reqVo.setId(addEntity.getId());
    reqVo.setApp(TEST_APP);
    reqVo.setGrade(FLOW_GRADE_QPS);
    reqVo.setCount(6D);
    reqVo.setInterval(2L);
    reqVo.setIntervalUnit(GatewayFlowRuleEntity.INTERVAL_UNIT_MINUTE);
    reqVo.setControlBehavior(CONTROL_BEHAVIOR_RATE_LIMITER);
    reqVo.setMaxQueueingTimeoutMs(500);
    GatewayParamFlowItemVo itemVo = new GatewayParamFlowItemVo();
    reqVo.setParamItem(itemVo);
    itemVo.setParseStrategy(PARAM_PARSE_STRATEGY_URL_PARAM);
    itemVo.setFieldName("pa");
    given(sentinelApiClient.modifyGatewayFlowRules(eq(TEST_APP), eq(TEST_IP), eq(TEST_PORT), any())).willReturn(true);
    MockHttpServletRequestBuilder requestBuilder = MockMvcRequestBuilders.post(path);
    requestBuilder.content(JSON.toJSONString(reqVo)).contentType(MediaType.APPLICATION_JSON);
    // Do controller logic
    MvcResult mvcResult = mockMvc.perform(requestBuilder)
            .andExpect(MockMvcResultMatchers.status().isOk())
            .andDo(MockMvcResultHandlers.print()).andReturn();
    // Verify the modifyGatewayFlowRules method has been called
    verify(sentinelApiClient).modifyGatewayFlowRules(eq(TEST_APP), eq(TEST_IP), eq(TEST_PORT), any());
    Result<GatewayFlowRuleEntity> result = JSONObject.parseObject(mvcResult.getResponse().getContentAsString(), new TypeReference<Result<GatewayFlowRuleEntity>>() {
    });
    assertTrue(result.isSuccess());
    GatewayFlowRuleEntity entity = result.getData();
    assertNotNull(entity);
    assertEquals(RESOURCE_MODE_ROUTE_ID, entity.getResourceMode().intValue());
    assertEquals("httpbin_route", entity.getResource());
    assertEquals(6D, entity.getCount().doubleValue(), 0);
    assertEquals(2L, entity.getInterval().longValue());
    assertEquals(GatewayFlowRuleEntity.INTERVAL_UNIT_MINUTE, entity.getIntervalUnit().intValue());
    assertEquals(CONTROL_BEHAVIOR_RATE_LIMITER, entity.getControlBehavior().intValue());
    assertEquals(0, entity.getBurst().intValue());
    assertEquals(500, entity.getMaxQueueingTimeoutMs().intValue());
    assertEquals(date, entity.getGmtCreate());
    // To make sure gmtModified has been set and it's different from gmtCreate
    assertNotNull(entity.getGmtModified());
    assertNotEquals(entity.getGmtCreate(), entity.getGmtModified());
    // Verify the entity which is update in memory repository
    GatewayParamFlowItemEntity itemEntity = entity.getParamItem();
    assertEquals(PARAM_PARSE_STRATEGY_URL_PARAM, itemEntity.getParseStrategy().intValue());
    assertEquals("pa", itemEntity.getFieldName());
}