【问题标题】:Avoid making actual Rest call in RestTemplate Junit避免在 RestTemplate Junit 中进行实际的 Rest 调用
【发布时间】:2021-05-21 12:32:23
【问题描述】:

下面是我使用 RestTemplate 的 EmployeeService,我为此编写了正在工作的 Junit。但问题是我的 JUNIT 正在对 Rest 端点进行实际调用。如何避免进行实际的 rest 调用?

@Service
public class EmployeeService {
    
    
    private RestTemplate restTemplate = new RestTemplate();

    public Employee getEmployee(String id) {
    ResponseEntity resp = 
          restTemplate.getForEntity("http://localhost:8080/employee/" + id, Employee.class);
        
    return resp.getStatusCode() == HttpStatus.OK ? resp.getBody() : null;
    }
}

@RunWith(MockitoJUnitRunner.class)
public class EmployeeServiceTest {

    @Mock
    private RestTemplate restTemplate;

    @InjectMocks
    private EmployeeService empService = new EmployeeService();

    @Test
    public void givenMockingIsDoneByMockito_whenGetIsCalled_shouldReturnMockedObject() {
        Employee emp = new Employee(“E001”, "Eric Simmons");
        Mockito
          .when(restTemplate.getForEntity(
            “http://localhost:8080/employee/E001”, Employee.class))
          .thenReturn(new ResponseEntity(emp, HttpStatus.OK));
 
        Employee employee = empService.getEmployee(id); **// Actual call happens .How to avoid it.**
        Assert.assertEquals(emp, employee);
    }
}

【问题讨论】:

  • 我认为问题是你正在初始化服务实体,试试@InjectMocks private EmployeeService empService;;
  • 它仍然进行实际调用。我刚刚修改了我的 EmployeeService 代码。我没有自动装配 RestTemplate 对象
  • 删除new EmployeeService。此外,您不应该创建一个新的RestTemplate,而是在您的服务中使用 Spring 注入它(使用 @Bean 方法中的 RestTemplateBuilder 创建一个)。
  • @M.Deinum 解决方案正在运行。谢谢

标签: spring spring-boot junit mocking spring-boot-test


【解决方案1】:

您正在创建一个显式的 new RestTemplate();

所以,你不能嘲笑它。

一种方法是创建一个执行实际调用的@Component。

@Component
public class MyHttpClient {

public ResponseEntity callingMethod(RestTemplate restTemplate, String id) {
restTemplate.getForEntity("http://localhost:8080/employee/" + id, Employee.class);
}
}

所以,你从类中调用它

@Service
public class EmployeeService {

@Autowired
private myHttpClient MyHttpClient;    
    
    private RestTemplate restTemplate = new RestTemplate();

    public Employee getEmployee(String id) {
        ResponseEntity resp = myHttpClient.callingMethod(restTemplate, id);
...
    }
}

从测试中你模拟了新的类和你什么时候:

@Mock
private MyHttpClientMock myHttpClientMock;

when(myHttpClientMock.callingMethod(Mockito.<RestTemplate> any()).thenReturn(HttpStatus.OK);

【讨论】:

  • 不相关的代码。你可能还没有看到我的完整代码
  • 是什么让你这么想?也许如果你试一试你会发现它很有用
  • 因为你也没有提供完整的代码。它缺少我实际调用方法Employee employee = empService.getEmployee(id)的实际问题
  • 这个调用保持不变。你不必改变它。为了简单起见,我已经缩小了更改范围。
  • 我得到了 NPE。不工作。请发布完整的可测试代码
【解决方案2】:

您需要将测试更改为模拟

public Employee getEmployee(String id) 

通过做

doReturn(emp).when(empService).getEmployee(1);//or a wild card

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-12-10
    • 2015-12-04
    • 2019-01-15
    • 2019-05-26
    • 1970-01-01
    • 2019-06-08
    • 2021-05-21
    相关资源
    最近更新 更多