【问题标题】:Integration test sleuth with restTemplate与 restTemplate 的集成测试侦探
【发布时间】:2017-03-07 10:13:35
【问题描述】:

我有一个运行代码,带有 spring boot 和 spring cloud,使用 sleuth 来记录 TraceId。但是我在集成测试中从另一个控制器调用一个控制器时遇到问题

  public class TraceIdApp {

    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }

    public static void main(String[] args) {
        SpringApplication.run(TraceIdApp.class, args);
    }

    }

    @Slf4j
    @Getter
    @RestController
    public class TraceIdController {

    private SpanAccessor spanAccessor;
    private RestTemplate restTemplate;
    private String url;

    @Autowired
    public TraceIdController(SpanAccessor spanAccessor, RestTemplate restTemplate,
            @Value("http://localhost:${local.server.port:${server.port:8080}}/other") String url) {
        this.spanAccessor = spanAccessor;
        this.restTemplate = restTemplate;
        this.url = url;
    }

    @GetMapping(path = "/")
    public String handlerOne() {
        long traceId = spanAccessor.getCurrentSpan().getTraceId();
        log.info("loggin the real traceId => " + traceId);
        String response = getRestTemplate().getForObject(getUrl(), String.class);

        return "one" + response;
    }

    @GetMapping(path = "/other")
    public String handlerOther() {
        long traceId = spanAccessor.getCurrentSpan().getTraceId();
        log.info("loggin the real traceId => " + traceId);
        return "other";
    }
}

@Getter
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
@AutoConfigureMockMvc
public class TraceIdAppTest {

    @Autowired
    private SpanAccessor spanAccessor;

    @Autowired
    private MockMvc mockMvc;
    @Value("http://localhost:${local.server.port:${server.port:8080}}/other")
    String url;

    @Test
    public void test() throws Exception {
        mockMvc.perform(get("/")).andExpect(status().isOk());
        assertTrue("trace is wrong type", getSpanAccessor() instanceof DefaultTracer);
    }
}

首先在测试中运行,我注意到 url 上的端口在测试中采用了正确的值,但在控制器上它的值为零。硬编码端口并没有解决问题。

【问题讨论】:

    标签: java spring integration-testing spring-restcontroller spring-cloud-sleuth


    【解决方案1】:

    我认为这与 Sleuth 无关。您正在使用 @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) 。所以端口将在某个点设置为绑定端口。最初它将等于 0,这就是为什么将值等于 0 的端口注入控制器的原因。您可以稍后尝试通过 setter 注入端口(例如 https://github.com/spring-cloud/spring-cloud-contract/blob/master/samples/standalone/pact/pact-http-client/src/test/java/com/example/loan/LoanApplicationServiceTests.java#L30-L36 )。在您的情况下,您应该在发送请求或测试准备好运行时解析端口的值。

    【讨论】:

    • 感谢您的快速回答,是的,我看到问题是控制器在测试前初始化,显然是在设置端口之前初始化。我认为真正的问题是为什么?或者怎么改?不做类似你的解决方案或这个@Before public void before() { ReflectionTestUtils.setField(controller, "url", url); } 甚至将控制器标记为惰性,它应该是另一种方式
    • 为什么要将自己的端口注入自己的控制器。这没有道理。您应该在测试中懒惰地解决这个问题。其他任何事情都只是做不正当的事情。
    猜你喜欢
    • 2021-11-03
    • 2014-11-12
    • 2018-08-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-21
    相关资源
    最近更新 更多