Spring Boot 模拟数据库和来自端点的响应

5hcedyr0  于 2023-04-06  发布在  Spring
关注(0)|答案(4)|浏览(166)

bounty已结束。回答此问题可获得+50声望奖励。奖励宽限期将在2小时后结束。Peter Penzov正在寻找来自信誉良好的来源的答案

我想为这段代码创建一个JUnit测试:

private Service listsService;
    
    
@RequestMapping(method = {RequestMethod.GET}, path = {"id/{id}"})
    public ResponseEntity<Object> find(@PathVariable String id) {
    
        LookupResponse lookupResponse = listsService.findById(id);
        return new ResponseEntity<>(lookupResponse, HttpStatus.OK);
    }
    
       .................
    
@Override
public LookupResponse findById(String id) {
    
    Optional<Lists> list = ListsRepository.findById(id);
    
    if(list.isPresent())
    {
        Lists lists = binList.get();
        LookupResponse response = LookupResponse.builder()
               .countryCode(lists.getCountry())
                        .category(lists.getType())
                        .build())
               .build();
    
        return response;
    }
    
    return null;
}

我试过这个:

public class ControllerTest {

@MockBean
private ListsService listsService;

@Autowired
private MockMvc mockMvc;

@Test
void justAnExample() {

    LookupResponse lookupResponse = LookupResponse.builder()
            .type("123456")
            .build();

    
   Mockito.when(listsService.findById(Mockito.anyString())).thenReturn(lookupResponse);

}

}
当我运行代码时,JUnit代码正在向数据库发出请求。我如何模拟连接?

bxgwgixi

bxgwgixi1#

为了使用@MockBean,如果使用JUnit 4,则需要使用或@ExtendWith(SpringExtension.class)@RunWith(SpringRunner.class)来注解测试类。您还可以使用@SpringJUnitConfig,它将@ExtendWith(SpringExtension.class)@ContextConfiguration结合在一起。请参阅https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/test/context/ContextConfiguration.html
其余的可以保持不变:

@ExtendWith(SpringExtension.class)
public class ControllerTest {

@MockBean
private ListsService listsService;

@Autowired
private MockMvc mockMvc;

@Test
void justAnExample() {

    LookupResponse lookupResponse = LookupResponse.builder()
            .type("123456")
            .build();

    
   Mockito.when(listsService.findById(Mockito.anyString())).thenReturn(lookupResponse);

}
9jyewag0

9jyewag02#

1.以下是测试中WebClient mocking的示例:https://www.baeldung.com/spring-mocking-webclient
1.对于测试中的RestTemplate mocking:https://www.baeldung.com/spring-mock-rest-template
要模拟数据库,这取决于你想实现什么。
1.您可以使用模拟数据库存储库
Mockito.when(mock.findById(id)).thenReturn(mockedresponse)
1.此外,还可以使用src/test/resources/application.properties覆盖src/main/resources/application.properties中的属性,并将spring test context连接到H2数据库,请阅读示例:https://www.baeldung.com/spring-testing-separate-data-source

fcy6dtqo

fcy6dtqo3#

您使用@MockBean模拟ListsService,但没有使用@Autowired@InjectMocks将其注入控制器。因此,控制器仍然使用真实的的ListsService而不是模拟的ListsService,因此进行真实的数据库调用。
要解决此问题,请尝试使用@Autowired或@InjectMocks注解将模拟的ListsService注入控制器。
它看起来类似于以下代码

@Mock 
ListsRepository listsRepository;

@InjectMocks
ListsService listsService = new ListsServiceImpl();

@Test
void justAnExample() {
    LookupResponse lookupResponse = LookupResponse.builder()
            .type("123456")
            .build();
    when(listsRepository.findById(anyString())).thenReturn(Optional.of(new Lists()));
    when(listsService.findById(anyString())).thenReturn(lookupResponse);

    mockMvc.perform(get("/id/1"))
            .andExpect(status().isOk())
            .andExpect(jsonPath("$.type", equalTo("123456")));
}
8fq7wneg

8fq7wneg4#

要模拟到数据库的连接,您可以使用Sping Boot 提供的@MockBean注解,它允许您模拟应用程序上下文中的bean,在您的情况下,您可以模拟ListsRepository bean,它负责访问数据库。
下面是一个如何操作的示例:

@RunWith(SpringRunner.class)
@WebMvcTest(controllers = Controller.class)
public class ControllerTest {

    @Autowired
    private MockMvc mockMvc;

    @MockBean
    private ListsService listsService;

    @MockBean
    private ListsRepository listsRepository;

    @Test
    public void testFind() throws Exception {
        // create a LookupResponse object to be returned by the mock service
        LookupResponse lookupResponse = LookupResponse.builder()
                .countryCode("US")
                .category("foo")
                .build();

        // configure the mock service to return the LookupResponse object
        when(listsService.findById("1")).thenReturn(lookupResponse);

        // configure the mock repository to return a Lists object when findById is called with "1"
        Lists lists = new Lists();
        lists.setCountry("US");
        lists.setType("foo");
        when(listsRepository.findById("1")).thenReturn(Optional.of(lists));

        // perform the HTTP GET request
        mockMvc.perform(get("/id/1"))
                .andExpect(status().isOk())
                .andExpect(content().json("{countryCode: 'US', category: 'foo'}"));
    }
}
// Fixed by FixThisCode.com

在本例中,我们使用@WebMvcTest注解来测试Controller类,这意味着只测试应用程序的Web层,而不是整个上下文。我们还使用@MockBean注解来模拟ListsService和ListsRepository bean。
在testFind()方法中,我们首先创建一个由模拟服务返回的LookupResponse对象。然后,我们配置模拟服务,使其在使用参数“1”调用其findById()方法时返回此对象。
我们还配置了模拟存储库,以便在使用参数“1”调用其findById()方法时返回Lists对象。服务将使用此对象创建LookupResponse对象。
最后,我们使用MockMvc对象对/id/1端点执行HTTP GET请求,并验证响应的状态码为200,JSON正文与预期的LookupResponse对象匹配。

相关问题