将ref参数设置为私有方法

时间:2017-03-07 10:13:39

标签: c# unit-testing

您好我是编码新手,尤其是单元测试,我试图找到一种方法将两个参考参数设置为私有方法,以便在不更改任何代码的情况下对其进行测试,例如:

  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);
    }
}

3 个答案:

答案 0 :(得分:1)

单元测试是您班级的客户端。它通过公共接口练习您的课程,并验证课堂行为是否符合预期。通过锻炼我的意思是尝试你班级的各种使用场景。

私人方法怎么样?

  • 为您的班级调用私有方法不是预期的使用方案。某些客户端可以使用反汇编程序查找私有成员详细信息,然后使用反射来调用它。但这并不是应该如何使用类。你有多少次打电话给DateTime班的私人成员?我打赌答案是零。因为您正在使用具有记录和预期行为的公共接口。
  • 任何私有成员都是实施细节。它可以随时重命名,重构或删除。没有保证。使用私人会员对客户来说是不安全的。测试私人会员对你来说是浪费时间。

您的类在公共接口中只有一个方法 - RefPrivateMethod(我希望实名更有意义)。这就是客户将使用的。那是你应该测试的。

答案 1 :(得分:0)

抱歉CorryM,

我认为您需要公开公开CompareTwoRefStrings方法才能使用单元测试对其进行测试。

您可以编写将为您执行此操作的接口方法,以免损害原始(CompareTwoRefStrings)方法的访问级别。

它只是语义,但单元测试应该只涵盖方法的基本功能。应该模拟所有其他功能,以便您的测试不会因先决条件的失败而失败。如果你试图覆盖RefPrivateMethod(如果这是一个真正的方法),那么你不是在编写单元测试 - 而是某种形式的集成测试,因为你不是只测试实际方法的逻辑但是CompareTwoRefStrings方法以及RefPrivateMethod调用的代码的任何其他部分。

PS 使用反射测试私有方法的方法也很脏,但我不建议这样做。

答案 2 :(得分:0)

知道如何通过测试设置参数,而不知道负责设置它们的代码通常是一个问题。 虽然您可以使用Typemock,但它们具有支持分配引用和输出参数的功能。 使用它时,你的测试会是这样的:

 [TestMethod]
public void TestMethod1()
{
    A classUnderTest = new A();
    string larger = "blablablabla", smaller = "b";

    Isolate.NonPublic.WhenCalled(classUnderTest,"CompareTwoRefStrings").AssignRefOut(smaller, larger).CallOriginal();

    var result = classUnderTest.RefPrivateMethod();

    Assert.AreEqual(larger, result);
}