2013-03-27 1 views
2

Java에서 소켓 응용 프로그램을 작성합니다. 서버에서 이벤트 소스의 메시지를 가져 와서 이벤트 유형에 따라 연결된 사용자에게 알림을 보냅니다.JUnit 모범 사례 - 공개 메서드로 결과를 확인할 수없는 테스트 메서드

이제 서버에 대한 JUnit 테스트를 작성하려고합니다 ... JUnit (Eclipse에서 자동으로 제안 됨)은 모든 공용 메소드에 대한 테스트를 구현하기 위해 필자에게 필요성을 알았습니다. 서버 클래스에는 public 메서드 bufferEvent ...가 있지만 이벤트는 개인 메서드에서 처리되며 버퍼링 된 메시지 수를 반환하는 메서드조차 없습니다.

따라서 서버에는 결과를 확인할 수있는 공용 메서드가 없습니다.

나는 문제가 일반화 될 수 있다고 생각 : 이 어떻게 결과가 공개 방법 (NO 게터 등) 난 그냥 테스트를 위해 추가 메소드를 작성하지 않도록 할

확인 할 수없는 공공 방법을 테스트 할 수 있습니다. 이 문제를 해결할 수있는 임시 해결책이나 모범 사례가 있습니까?

미리 감사드립니다.

+0

아마도 반사가 도움이 될 수 있을까요? – Petr

+0

http://stackoverflow.com/questions/10141626/changing-private-methods-to-protected-for-testing – andersoj

+0

코드를 제공 할 수 있습니까? 우리 회사에는 TDD 코치가 있으며 몇 가지 트릭을 설명했지만 소스 코드에 따라 다양합니다. 때로는 메서드 결과를 테스트 할 필요가 없지만 일부 호출이 제대로 수행되었는지 확인해야 할 때도 있습니다. 때로는 설계 결함이 있고 개인적인 방법이 실제로 다른 클래스에 있어야하며 공개되어 테스트 할 수 있어야합니다. – ThanksForAllTheFish

답변

1

네거티브 테스트 케이스를 확인할 수 있습니다. 서비스로부터 반환은 없습니다하지만 어쩌면 서비스에 의해 슬로우되는 예외가있다 :

@Test 
public void testServerService(){ 
    myServer.service(); 
    Assert.assertTrue(true); 
} 

그래서 난 적어도에 있습니다

는 경우에 그렇지 않으면
@Test 
public void testServerService(){ 
try{ 
    myServer.service(); 
    Assert.assertTrue(true); 
}catch(Exception ex){ 
    Assert.fail("anything goes wrong"); 
} 
} 

나는 이런 식으로 뭔가를 쓰기는 프로세스가 문제없이 실행되는지 확인하는 어설 션

btw 나는 당신이 옳다고 생각합니다. Junit 테스트 케이스를 검증하기위한 새로운 기능을 작성하는 것은 매우 나쁜 습관입니다.

+0

'Assert.assertTrue (true)'는 중복 된 문장입니다. 테스트가 없으면 테스트가 성공적으로 완료됩니다. 예상과 예외가있는 경우'@Test (expected = YourException.class)'를 사용하거나 예외가 발생할 것으로 예상하지 않는 경우 사용하십시오. JUnit이 실패를 인쇄합니다. – Alex

+0

안녕하세요 스테판, 추가 기능을 피해야한다고 지적 해 주셔서 감사합니다. 응용 프로그램에 대한 테스트 연습입니다. 그리고 코드는 모범 사례를 따라야합니다 ... :) 그 일을 시작하지 않았다는 것이 좋았습니다. – ramin

2

공동 작업자를 위해 mock이나 스파이를 삽입 할 수있는 생성자를 만들어야합니다.

예를 들어 서버에는 생성자 Server(List<Buffer> buffer)이 있습니다. 테스트 용으로 만 사용됩니다. 그런 다음 단위 테스트에서 버퍼를 추가하고 해당 버퍼가 수정되었음을 주장 할 수 있습니다.

테스트에서 생성 한 개체로 쉽게 교체 할 수 있습니다. 고급 기능을 원하면 Mockito과 같은 조롱하는 프레임 워크를 살펴보십시오.

예를 들어 소켓에 대한 모의를 만듭니다. 너는 Socket = mock(Socket.class을 얻을 것이다. 생성자 Server(List<Buffer> buffer, Socket socket)에 삽입합니다. 그런 다음 테스트 할 함수를 호출 한 후 예를 들어 verify(socket).send("yourMessage")을 사용하여 서버가 "yourMessage"매개 변수와 함께 send 메소드를 사용했는지 확인할 수 있습니다.

예를 들어 this Plugins class에는 생성자에 몇 가지 플러그인이 필요합니다. 테스트하기 위해 모의 객체를 생성하고 삽입 한 다음 in this test class과 같이 확인합니다 : verify(proxyServerPlugin).proxyServer(config);.

더 많은 예제는 Mockito을 참조하십시오.

+0

안녕하세요 Alex, 모의 소리를 사용해 주셔서 감사합니다. 나는 테스트를 위해 mock 객체를 추가하기 위해 생성자를 생성해야하지만, 그렇게함으로써, 적어도 필요한 모든 mock을 construtcor에 추가함으로써 여러 함수를 테스트 할 수있다. – ramin

+0

확실히, 당신은'@ Google Guice에서 다른 개발자에게 테스트를 위해 생성자 만 알려주는 VisibleForTesting 주석이 있습니다. 물론 생성자 패키지를 보호하여 아무도이를 남용하지 않도록해야합니다. – Alex

+0

그 소리도 좋다. 불행히도 응용 프로그램 테스트 exersice 이후 제 3 자 라이브러리를 사용하기로되어 있습니다 ... – ramin

0

로거를 추가하는 방법에 대해 생각해보십시오. 레벨 테스트에서는 메서드의 끝에 중요한 값을 로깅하고 테스트 클래스에 대한 스트림을 보유합니다.

+0

그래, 그건 좋은 생각이 아니야. 반사가 잘 작동합니다! – ramin