【问题标题】:How to debug a Spring Boot application via SpringBootTest如何通过 SpringBootTest 调试 Spring Boot 应用程序
【发布时间】:2017-06-21 00:06:52
【问题描述】:

我是 Spring Boot 的新手,我非常喜欢它,尤其是在消除样板代码方面。 我创建了一个测试类来测试我的NBRController:

@RunWith(SpringRunner.class)
@SpringBootTest(classes = NewBusinessRevitalizationApplication.class, 
    webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@TestPropertySource(properties = {"management.port=0"})
public class NBRControllerTest extends TestCase {

    @LocalServerPort
    private int port;

    @Value("${local.management.port}")
    private int mgt;

    @Autowired
    private TestRestTemplate testRestTemplate;

    @Test
    public void getApplicationByAgencyIdAndStatusTest() {
        String uri = "http://localhost:" + this.port + "/nbr-services/applications/{status}?agencyIds=123456,56765,678576";
        Map<String, String> vars = new HashMap<String, String>();
        vars.put("status", "SAVED");
        ResponseEntity<String> response = testRestTemplate.getForEntity(uri, String.class, vars);
        assertEquals(HttpStatus.OK, response.getStatusCode());
    }
}

如果我在调试模式下运行它,我只能调试 Test 类而不是我的 NBRController 类:

@RestController
@RequestMapping("/nbr-services")
public class NBRController {

    @Autowired
    private NBRServices nbrServices;

    private static Logger logger = LoggerFactory.getLogger(NBRController.class);

    @RequestMapping(value = "/configuration/environment/{environment}", method = RequestMethod.GET)
    @ResponseBody
    public String getConfiguration(@PathVariable("environment") String environment) throws RemoteException {
        logger.debug("environment={}", environment);
        String result = nbrServices.getConfiguration(environment);
        return result;
    }
}

我尝试设置 Tomcat 调试端口,但运气不佳。 我可以调试NBRController 的唯一方法是在调试模式下运行它并从浏览器调用我的 RestAPI,但我想使用我的单元测试。提前致谢!

【问题讨论】:

标签: spring-boot testing spring-test


【解决方案1】:

我正在使用 Intellij 2020.3,我可以调试我的控制器。

  1. 从 intellij 停止所有正在运行的实例。 2.只需将调试指针放在正确的控制器方法中,并在调试模式下运行您的测试用例。
  2. 除非您遇到错误的端点,否则它应该可以工作。
  3. 您还可以尝试在调试模式下在测试用例中评估您的 testRestTemplate 调用,以防网络本身出现故障。

【讨论】:

    【解决方案2】:

    就个人而言,我使用 maven-spring-boot 插件,当我调试时,它来自 Maven 运行配置。也许这就是你正在做的事情有什么问题? maven-spring-boot插件,在测试阶段,会在测试运行前启动spring boot server。

    如果您想使用命令行应用程序执行此操作,则必须在测试运行之前手动加载 Spring 上下文并从几行代码执行主类。我不记得该怎么做。

    【讨论】:

      【解决方案3】:

      这里是为 Spring boot 2 + JUnit 5 的 Rest 层编写 Junit 的示例

      @ExtendWith(MockitoExtension.class)
      public class RestTest {
      
          @InjectMocks
          private Rest  rest;
          
          private MockMvc mockMvc;
          
          @BeforeEach
          public void init() throws Exception {
              MockitoAnnotations.initMocks(this);
              mockMvc = MockMvcBuilders.standaloneSetup(rest).build();
          }
          
          @Test
          public void getTest() throws Exception {
              String url = "/test";
              ResultActions resultActions = mockMvc.perform(get(url));
              resultActions.andExpect(status().isOk());
      
          }
          
      }
      
          @RestController
          @RequestMapping(value = "/test", produces = MediaType.APPLICATION_JSON_VALUE)
          public class Rest  {
          
              
              
              @GetMapping
              public @ResponseBody String get()  {
                  
                  return "success";
              }
              }
      

      【讨论】:

        【解决方案4】:

        当我不小心有 2 个具有相同路径映射的控制器方法时,我遇到了这种情况。

        其他调试方法:

        仅使用 mockMVC 模拟服务器

        可以不使用拆分的 webEnvironment 来调试系统,而是使用 spring MockMVC 对控制器进行直接方法调用而不是 http 调用。

        @SpringBootTest(
           webEnvironment = SpringBootTest.WebEnvironment.MOCK // this is the default
        )
        @AutoConfigureMockMvc
        class MyTest {
        
          @Autowired
          private MockMvc mockMvc;
        
          @Test public void myTest() {
             mockMvc.perform("/mypath");
             // ...
          }
        }
        

        这实际上不会在 jUnit 类和控制器之间进行 http 调用,因此不会测试这个 http 处理部分。

        单独启动服务器并附加远程调试器

        1. 在 IDE 中,以调试模式启动应用程序
        2. 当应用程序启动并运行时,启动包含任何 http 客户端的 JUnit 测试,例如放心。

        这将生成 2 个 JVM,但 IDE 连接到这两个 JVM,因此所有断点都有效。

        【讨论】:

          【解决方案5】:

          在 Uri 中,您要附加 http://local host +port ,这不是必需的,testRestTemplate 会为您完成。删除它并尝试您可能会达到调试点

          【讨论】:

          • 如果这不起作用,请告诉我,我正在通过手机回答。明天从电脑发送
          【解决方案6】:

          您可能在与您认为的端口不同的端口上运行。

          SpringBootTest 注解控制测试端口,例如

          @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
          

          【讨论】:

          • 你能解释一下如何调试RestController吗?我已更改为 SpringBootTest.WebEnvironment.DEFINED_PORT 有你的建议,但仍然跳过刹车点。
          • 在您的设置调试中应该可以正常工作。要检查的一件事是,您的休息呼叫将发送到您认为的服务器。您是否有任何其他未处于调试模式的实例正在运行?强制端口与规范不同,例如server.port=9123 在 application.properties/yaml 中,然后在开始测试时执行 netstat 以检查它是否已启动并运行。还可以尝试在 postConstruct 方法中的一行上放置一个断点,以向自己证明您正在访问您在测试中启动的应用程序。
          • 我正在使用正确的服务,因为是 @SpringBootTest 启动服务来调用,问题是从 Intellij 如果我在调试模式下运行单元测试,它会在调试模式下运行测试而不是服务
          • 你找到这个问题的答案了吗?
          • 据我所知,您需要的是嵌入式 Spring 应用程序的远程调试能力。我有类似的要求。看起来SpringBootTest 正在内部运行它。如果我有办法指定调试端口,我就能做到。到目前为止,我必须单独运行我的应用程序。
          猜你喜欢
          • 2020-03-18
          • 2022-11-11
          • 1970-01-01
          • 2020-06-17
          • 1970-01-01
          • 2017-05-28
          • 2018-05-13
          • 2015-03-09
          • 1970-01-01
          相关资源
          最近更新 更多