2017-11-19 2 views
0

나는 하나의 방법 아래와 같이가에 File.delete를() 함수를 테스트하는 방법 :Junit와

public final class someTask { 
    public void sampleMethod(String filePath) { 
     //It is calling Files.delete() method. 
     Files.delete(new File(filePath).toPath) 
    } 
} 

내가 테스트 케이스 (즉, 파일 등의 유효한 파일 매개 변수 여부 예 ValidRecord위한) 방법 위의 테스트 , 대부분의 경우 내 테스트 케이스가 실패했습니다. 위의 경우를 테스트하는 방법을 알려줄 수있는 사람이 있습니까?

내가 Files.deplete() 메소드를 테스트하기 위해 계획하고 있지 않다,이에

@Mock 
File fileMock; 

@Rule 
ExpectedException exception = ExpectedException.none(); 

PowerMockito.whenNew(File.class).withArguments(VALID_Path).thenReturn(fileMock); 
PowerMockito.when(fileMock.exists()).thenReturn(true); 
PowerMockito.when(fileMock.isFile()).thenReturn(true); 

을 니펫을 아래에 사용하고 있지만 내 자신의 방법의 테스트 동작을 계획하고 파일을 얻으려면. 그 과정에서 매번 "java.nio.file.NoSuchFileException"예외가 발생하여 임시 파일을 생성합니다.

몇 가지 예를 들어 테스트 할 수 있습니다.

+0

'TemporaryFolder'? –

+1

1. 왜 다른 사람의 코드를 테스트하고 있습니까? 2. 당신은 mock을 사용할 필요가 없다는 것을 알고 있습니다. * 실제 * 파일을 만들고, 메소드를 호출하고, 그것이 존재하지 않는지 확인하십시오;) – alfasin

+0

응용 프로그램을 테스트하십시오. 플랫폼을 테스트하지 마십시오. 그들은 이미 당신을 위해, 당신이 상상할 수있는 것보다 더 강력하게합니다. – EJP

답변

3

조롱과 상호 작용을 통해 행동을 확인함으로써 사용자의 접근 방식이 잘못되었다고 주장 할 수 있습니다. 나는 다음과 같은

  • 는 로컬 파일 시스템

  • 호출 방법 sampleMethod

  • 파일이 더 이상 존재하지 않는다는 것을 확인에 임시 파일을 생성 할 것입니다.
0

이러한 종류의 질문에 대한 유용한 접근 방식은 한 걸음 뒤로 물러나 응용 프로그램 디자인을 비판하는 것입니다. 디자인 문제가 있는지, 특히 코드 테스트가 약간 어려울 것으로 생각되는 경우 자신에게 물어보십시오.

참으로 : 소프트웨어 디자인을 개선 할 수 있습니까?

public final class SomeTask { 
    public void sampleMethod(String filePath) { 
     Files.delete(new File(filePath).toPath); 
    } 
} 

내가 예외를 무시하기 위하여려고하고있다 :

이의이 클래스부터 시작하자 (BTW, 나는-케이스 낙타하기 위해 이름을 변경). 또한, 여러분의 코드 어딘가에 당신은이 클래스를 사용하고 있습니다 :

SomeTask task = new SomeTask(); 
String filePath = ... 
task.sampleMethod(filePath); 

가장 먼저하는 일을 실현하기 위해 : 클래스에서 당신은 삭제-A-파일 기능에 대한 종속성이 SomeTask. 이 종속성을 볼 수있게하십시오!

하지만 어떻게 할 수 있습니까? 이제 이러한 deletor에 대한 필드를 추가하여 클래스를 변경할 수 있습니다

@FunctionalInterface 
public interface FileDeletor { 
    void delete(String filePath); 
} 

: 인터페이스로이 방법을

public final class SomeTask { 
    private final FileDeletor deletor; 

    public SomeTask(FileDeletor deletor) { 
     this.deletor = Objects.requireNonNull(deletor); 
    } 

    public void sampleMethod(String filePath) { 
     deletor.delete(filePath); 
    } 
} 

당신은 지금 다른 클래스에 파일 삭제의 기술적 행함을 위임 인터페이스를 구현해야합니다 (아래 참조). 이것은 또한 이제 자신의 기능 (들)에 집중할 수 있기 때문에 클래스를보다 일관성있게 만듭니다.난 아직 여기에 예외를 무시하고 있다는

public final class DefaultFileDeletor implements FileDeletor { 
    @Override 
    public void delete(String filePath) { 
     Files.delete(new File(filePath).toPath()); 
    } 
} 

참고 :

우리는 이제 인터페이스를 구현하는 클래스가 필요합니다. 당신은 또한 봄에서 autowiring 또는 유사한 의존성 주입 프레임 워크를 통해 애플리케이션을 구축 할 수 있습니다이 방법

FileDeletor deletor = new DefaultFileDeletor(); 
SomeTask task = new SomeTask(deletor); 
String filePath = ... 
task.sampleMethod(filePath); 

: 이제 우리는 또한 사용하여면을 변경해야합니다.

테스트 영역으로 넘어 갑시다. 원하는 경우 새 클래스 DefaultFileDeletor을 테스트 할 수도 있습니다. 하지만 JDK의 기능 만 사용한다는 것을 알고 있습니다. 이 간단한 클래스를 테스트 할 필요가 없습니다.

하지만 이제 어떻게 수업을 테스트 할 수 있습니까 SampleTask? 첫째, 당신은 단지 테스트의 목적을 위해 인터페이스의 구현이 필요합니다

FileDeletorForTestPurposes deletor = new FileDeletorForTestPurposes(); 
SomeTask task = new SomeTask(deletor); 
String filePath = ... 
task.someMethod(filePath); 
assertEquals(filePath, deletor.getFilePath()); 
assertEquals(true, deletor.isDeleted()); 

또한 이제 단순히 FileDeletor 모형을 만들 수 있습니다 :

public class FileDeletorForTestPurposes implements FileDeletor { 
    private String filePath; 
    private boolean deleted; 

    @Override 
    public void delete(String filePath) { 
     this.filePath = filePath; 
     deleted = true; 
    } 

    public String getFilePath() { 
     return filePath; 
    } 

    public boolean isDeleted() { 
     return deleted; 
    } 
} 

지금 당신은 당신의 코드를 테스트 할 수 있습니다 그것에 대한 기대를 표현함으로써 그것을 사용하십시오.