java 单元测试注释?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17261501/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-01 01:29:02  来源:igfitidea点击:

Unit testing annotations?

javaunit-testingannotations

提问by lappo

I'm asking myself how deep should I go in (unit) testing my classes. As example, I have following simple class .

我在问自己我应该深入(单元)测试我的课程。例如,我有以下简单的类。

import javax.annotation.security.PermitAll;
import javax.ejb.Singleton;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;


@Path(value = "ping")
@Singleton
@PermitAll
public class PingRestService {

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String pingMethod(){
        return "pong";
    }

}

I wrote following unit test:

我写了以下单元测试:

import static org.junit.Assert.*;
import java.lang.reflect.Method;
import javax.annotation.security.PermitAll;
import javax.ejb.Singleton;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

import org.junit.Test;


public class PingRestServiceTest {

    PingRestService prs = new PingRestService();

    @Test
    public void testClassAnnotations(){
        assertEquals(3, prs.getClass().getAnnotations().length);

        assertTrue(prs.getClass().isAnnotationPresent(PermitAll.class));
        assertTrue(prs.getClass().isAnnotationPresent(Singleton.class));
        assertTrue(prs.getClass().isAnnotationPresent(Path.class));

        assertEquals("ping", prs.getClass().getAnnotation(Path.class).value());

    }

    @Test
    public void testPingMethodAnnotations() throws SecurityException, NoSuchMethodException{

        Method method = prs.getClass().getDeclaredMethod("pingMethod");
        assertEquals(2, method.getAnnotations().length);

        assertTrue(method.isAnnotationPresent(GET.class));
        assertTrue(method.isAnnotationPresent(Produces.class));

        assertEquals(1, method.getAnnotation(Produces.class).value().length);
        assertEquals(MediaType.TEXT_PLAIN, method.getAnnotation(Produces.class).value()[0]);
    }

    @Test
    public void testPingMethod() {
        assertEquals("pong", prs.pingMethod());
    }

}

does it make sense? Or should I only test the returning string ("pong", testPingMethod), skipping all annotations tests (testClassAnnotations,testPingMethodAnnotations) ?

是否有意义?或者我应该只测试返回的字符串(“pong”,testPingMethod),跳过所有注释测试(testClassAnnotations,testPingMethodAnnotations)?

I think some annotations are part of a business logic (e.g. PermitAll), and therefore should be tested.

我认为一些注释是业务逻辑的一部分(例如 PermitAll),因此应该进行测试。

采纳答案by Sandro

Most of the time one tests the functionality of the code and not the way it is implemented. This is called Black Box Testing(see: http://en.wikipedia.org/wiki/Black-box_testing). When implementing a test you should ask yourself: "What are the possible input values of the unit to test and what are the expected results?" Now in the test you call your code with the input values and check the result with the expected one to make sure your code behaves the way you want it. Over time you might optimize the code without wanting to change the functionality. Then you should not need to change your test. But you can re-run it to make sure it still behaves the same way. Even if it is implemented differently. Or you might make change implementation details that have side effects to the functionality you tested. Also in this case you don't need to change the test but you just need to re-run it. In your simple case you have no input and one static output so you can just call the method and check if "pong" is returned. But real life cases that are tested are rarely that simple.

大多数时候测试代码的功能而不是它的实现方式。这称为Black Box Testing(参见:http: //en.wikipedia.org/wiki/Black-box_testing)。在实施测试时,您应该问自己:“要测试的单元的可能输入值是什么,预期结果是什么?” 现在在测试中,您使用输入值调用您的代码,并使用预期的值检查结果,以确保您的代码按您希望的方式运行。随着时间的推移,您可能会优化代码而不想更改功能。那么你应该不需要改变你的测试。但是您可以重新运行它以确保它的行为方式仍然相同。即使它的实现方式不同。或者,您可能会更改对您测试的功能有副作用的实现细节。同样在这种情况下,您不需要更改测试,而只需要重新运行它。在您的简单情况下,您没有输入和一个静态输出,因此您只需调用该方法并检查“pong” 被退回。但是经过测试的现实生活案例很少如此简单。

Edit: You can see the security that @PermitAllconfigures and the URL path that '@Path' configures as inputs and also test them in an integration test the way 'Boris the Spider' and 'Avi' suggested. But the other annotations are implementation specific.

编辑:您可以看到@PermitAll配置的安全性和“@Path”配置为输入的 URL 路径,还可以按照“Boris the Spider”和“Avi”建议的方式在集成测试中测试它们。但是其他注释是特定于实现的。

回答by alex.net

In my opinion those annotations are aspects of your class and not the essence of it, its real purpose, so shouldn't be unit tested. Maybe tomorrow you will use Spring MVC instead of JAX-RS, but your class would have the same behavior so the unit test should be the same

在我看来,这些注释是你的类的方面,而不是它的本质,它的真正目的,所以不应该进行单元测试。也许明天您将使用 Spring MVC 而不是 JAX-RS,但是您的类将具有相同的行为,因此单元测试应该相同