programing

테스트 클래스에 대해서만 비공개 방법을 공개하기 위한 주석

goodjava 2022. 11. 2. 00:30

테스트 클래스에 대해서만 비공개 방법을 공개하기 위한 주석

그 공통의 요구에 대한 해결책을 가지고 있는 사람.

저는 수강신청을 하고 있습니다.

api의 일부로서 공개되어 있는 메서드와 내부 플로우를 보다 읽기 쉽게 하기 위한 내부 사용을 위한 프라이빗 메서드도 있습니다.

예를 들어 유닛 테스트 또는 통합 테스트와 같은 것을 쓰고 싶다고 합시다.이것은 다른 패키지에 배치되어 이 메서드를 호출할 수 있지만, 어플리케이션 자체의 클래스에서 호출하려고 하면 이 메서드에 대한 일반 호출이 허용되지 않습니다.

그래서 그런 생각을 하고 있었는데

public class MyClass {

   public void somePublicMethod() {
    ....
   }

   @PublicForTests
   private void somePrivateMethod() {
    ....
   }
}

위의 주석에서는 개인 메서드를 "테스트용 공개"로 표시합니다. 즉, 테스트 중인 모든 클래스에 대해 컴파일 및 실행 시간이 허용됩니다.테스트 패키지에 포함되지 않은 클래스는 컴파일 및 런타임에 실패합니다.

무슨 생각 있어?이런 주석이 있나요?더 좋은 방법은 없을까?

더 많은 단위 테스트를 작성할수록 캡슐화를 깨기 위해 더 많은 정보를 얻을 수 있는 것 같습니다.

일반적인 방법은 프라이빗 메서드를 보호 또는 패키지 프라이빗으로 하고 이 메서드의 유닛테스트를 테스트 대상 클래스와 같은 패키지에 넣는 것입니다.

Guava에는 주석이 있지만 문서화를 위한 것일 뿐입니다.

테스트 대상 클래스 내의 모든 공개 메서드에서 테스트 범위가 양호한 경우 가능한 모든 경우를 주장하기 때문에 공개 메서드에서 호출된 비공개 메서드가 자동으로 테스트됩니다.

JUnit Doc는 다음과 같이 말합니다.

개인 메서드를 테스트하는 것은 재사용 가능성을 높이기 위해 이러한 메서드를 다른 클래스로 이동해야 한다는 것을 나타냅니다.하지만 꼭 그래야 한다면...JDK 1.3 이후를 사용하고 있는 경우 리플렉션을 사용하여 특권 접근컨트롤 메커니즘을 전복시킬 수 있습니다.사용 방법에 대한 자세한 내용은 이 문서를 참조하십시오.

인터페이스를 사용하여 API 메서드를 공개하고 팩토리 또는 DI를 사용하여 오브젝트를 퍼블리시하여 소비자가 인터페이스로만 오브젝트를 알 수 있도록 합니다.인터페이스는 공개된 API를 기술합니다.이렇게 하면 구현 객체에 대해 원하는 모든 것을 공개할 수 있으며, 이러한 객체의 소비자는 인터페이스를 통해 공개된 메서드만 볼 수 있습니다.

dp4j는 필요한 것을 가지고 있습니다.기본적으로는 클래스 패스에 dp4j를 추가하면 됩니다.@Test(JUnit의 주석)에 주석을 단 메서드가 프라이빗 메서드를 호출할 때마다 동작합니다(dp4j는 컴파일 시 필요한 리플렉션을 주입합니다).dp4j의 @TestPrivates 주석을 사용하여 보다 명확하게 할 수도 있습니다.

개인 메서드에 주석을 달아야 하는 경우 Google의 @VisibleForTesting 주석을 사용할 수 있습니다.

또는 이 메서드를 특정 전략 객체에 추출할 수 있습니다.이 경우 추출된 클래스를 쉽게 테스트할 수 있으며 반사/바이트 코드로 메서드나 매직은 공개하지 않습니다.

개인 메서드 테스트에 관한 기사에는 개인 코드를 테스트하는 몇 가지 방법이 나와 있습니다.리팩터링이 끝나면 스트링이 자동으로 변경되지 않지만 가장 깔끔한 방법이라고 생각합니다.

자, 여기 두 가지가 섞여 있습니다.첫 번째는 테스트에서만 사용할 수 있도록 표시를 해야 할 때인데, 저는 @JB Nizet에 동의하지만 guava 주석을 사용하면 좋을 것 같습니다.

또 다른 것은 개인 방법을 테스트하는 것입니다.왜 외부에서 개인 방법을 테스트해야 합니까?그러니까...퍼블릭 메서드로 오브젝트를 테스트할 수 있으며, 최종적으로 오브젝트의 동작을 테스트할 수 있습니다.적어도, 항상 개인 방법을 시험해 보려고 하는 후배 개발자에게 가르쳐 주려고 하고 있습니다(좋은 프랙티스로서).

나는 그러한 주석을 알지 못하지만, 다음 사항이 유용할 수 있다: 유닛 테스트 개인 방법
또는 다음 항목: JMockit

이럴 순 없어, 그 이후로 어떻게 시험지를 컴파일 할 수 있어?컴파일러는 주석을 고려하지 않습니다.

여기에는 두 가지 일반적인 방법이 있습니다.

첫 번째는 리플렉션(reflection)을 사용하여 메서드에 액세스하는 것입니다.

두 번째는 private가 아닌 package-private를 사용하여 테스트를 같은 패키지(단, 다른 모듈)로 하는 것입니다.기본적으로 다른 코드에는 비공개이지만 테스트에서는 액세스할 수 있습니다.

물론 블랙박스 테스트를 한다면 개인 회원에게 접근해서는 안 됩니다.

최근 리플렉션으로 개인 필드, 메서드, 내부 클래스 접근에 많은 도움을 주는 라이브러리 BoundBox를 출시하였습니다.

같은 반의 경우

public class Outer {
    private static class Inner {
        private int foo() {return 2;}
    }
}

다음과 같은 구문을 제공합니다.

Outer outer = new Outer();
Object inner = BoundBoxOfOuter.boundBox_new_Inner();
new BoundBoxOfOuter.BoundBoxOfInner(inner).foo();

BoundBox 클래스를 만들기 위해 해야 할 일은 쓰기뿐입니다.@BoundBox(boundClass=Outer.class)및 그BoundBoxOfOuter클래스가 즉시 생성됩니다.

내가 아는 한 이런 주석은 없다.가장 좋은 방법은 다른 사람들이 제안한 것처럼 반성을 이용하는 것이다.이 투고를 봐 주세요.
개인 메서드, 필드 또는 내부 클래스가 있는 클래스를 테스트하려면 어떻게 해야 합니까?

메서드의 예외 결과를 테스트할 때만 주의해야 합니다.예를 들어, Ilgal Argument를 상정하고 있는 경우예외이지만 대신 "null"(클래스:java.lang.reflect)이 표시됩니다.InvocationTargetException).
제 콜레그 중 한 명이 이러한 상황에서 Powermock 프레임워크를 사용할 것을 제안했지만, 저는 아직 테스트하지 않았기 때문에 정확히 어떤 기능을 할 수 있는지 모릅니다.기반이 되는 Mockito 프레임워크를 사용하고 있습니다만, 그것도 좋은 프레임워크입니다(그러나 프라이빗 메서드의 예외 문제는 해결되지 않는다고 생각합니다).

@Public For Tests 주석을 달면 좋습니다.

건배!

저는 이 시험을 내부 수업으로 만들어서 수업 자체에 넣었을 뿐입니다.https://rogerkeays.com/how-to-unit-test-private-methods

언급URL : https://stackoverflow.com/questions/6913325/annotation-to-make-a-private-method-public-only-for-test-classes