2008-09-18 6 views
6

Java에서 JMock을 사용하여 객체 구성을 조롱하는 방법이 있습니까?대상 구조물을 조롱하는 방법?

, I는 다음과 같은 방법이 있다면 :

public Object createObject(String objectType) { 
    if(objectType.equals("Integer") { 
     return new Integer(); 
    } else if (objectType.equals("String") { 
     return new String(); 
    } 
} 

... 시험 방법에서 오브젝트 구조의 기대를 모의하는 방법이 있습니까?

필자는 특정 생성자가 호출되는 것을 기대할 수 있기를 바란다. 형식을 검사하기위한 여분의 비트가 아니라 (필자의 예처럼 항상 복잡하지는 않으므로).

그래서 대신

:

assertTrue(a.createObject() instanceof Integer); 

나는 특정 생성자의 기대를 가질 수가 호출된다. 그냥 좀 더 깔끔하게 만들고 실제로 더 쉽게 읽을 수있는 방법으로 테스트하고있는 것을 표현하십시오.

간단한 예를 용서하십시오, 나는 일하고 있어요 실제 문제는 좀 더 복잡하지만 기대를 가지는 것은 그것을 단순화 것입니다. 좀 더 배경에 대한


:

나는 래퍼 객체를 생성하는 간단한 팩토리 메소드를 가지고있다. 래핑 된 객체는 테스트 클래스에서 확보하기 어려운 매개 변수 (기존 코드)를 필요로하므로이를 구성하기가 어렵습니다.

제가 실제로 찾고 있어요에 아마 가까이 : 하나의 급습 (CGLIB를 사용하는) 전체 클래스를 조롱 할 수있는 방법이 밖으로 스텁하기 위해 모든 방법을 지정하지 않고? 그렇게 분명 방법이이를 호출 할 수 있도록 모의 생성자 래핑되는

는 각 동적 방법을 조롱 JMock 가능? 이 꽤 복잡 할 것처럼

내 생각은 전혀 없다. 하지만 잘못 짚었있어 알고 너무 :-)

+0

내 대답은 당신이있는 거 공장은 그것이 구성 수있는 각 유형 (정수 공장, 문자열 공장 등)하지만, 당신 말이 맞아 대한 자신의 공장입니다 가질 수를 참조하십시오, 그것은 지나치게 복잡쪽으로 기울고 있어요 . 당신은 아마 instanceof 테스트가 아마도 최선의 방법이라고 주장합니다. – sblundy

답변

5

제가 생각할 수있는 유일한 점은 당신이 모의하는 factory 객체에서 create 메소드를 사용하는 것입니다.

그러나 생성자 호출을 조롱하는 측면에서 보면. 모의 객체는 객체의 존재를 전제로하는 반면, 생성자는 객체가 존재하지 않는다고 전제합니다. 적어도 자바에서는 할당과 초기화가 함께 일어난다.

-1

나는 아무도 없다 희망 유용합니다. 모의 객체는 생성자가없는 인터페이스를 모의하기로되어 있습니다 ... 단지 메소드.

뭔가 여기 테스트에 당신의 접근 방식에 어긋 것 같다. 그 명시 적 생성자를 테스트해야하는 이유는 무엇입니까?
반환 된 객체의 유형을 명시하는 것은 팩토리 구현을 테스트하는 데는 문제가없는 것처럼 보입니다. createObject를 블랙 박스로 취급하십시오. 반환하는 대상을 조사하십시오. 아무도 그 것을 좋아하지 않아 :)

업데이트시 업데이트 : 아야! 필사적 인 시간을위한 필사적 인 측정은 어? JMock이 허용하는 경우 놀랄 것입니다 ... 내가 말했듯이 인터페이스에서는 작동합니다. 구체적인 유형이 아닙니다. 그래서

  • 시도 및 테스트 장치에서 그 성가신 입력 개체 '가 인스턴스화'얻기에 어떤 노력을 소비 하나. 당신의 접근 방식에서 바텀 업.
  • 이것이 불가능할 경우 수동으로 중단 점을 사용하여 테스트하십시오 (나는 싫증이납니다). 그런 다음 소스 파일의 보이는 영역에 "자신의 책임으로 터치하십시오"주석을 붙이고 앞으로 이동하십시오. 하루 더 싸우라.
+0

간단한 공장 방법입니다. 문제는 팩토리가 다른 객체에 대한 래퍼를 만들고 (생성 중에 매개 변수로 가져 오는) 래치를 반환한다는 것입니다. 래퍼중인 개체를 조롱하거나 인스턴스화하는 대신 생성자가 호출되고 있는지 테스트 할 수 있어야합니다. – Grundlefleck

+0

그 문제는 factory 메소드가 고립에서 다시 생성하기 어려운 객체를 사용한다는 것입니다. 리팩터링을 사용하면 지금 당장은 그다지 문제가되지 않습니다. 비록 ... 조롱하는 것은 아마 대답 일 것입니다 ... – Grundlefleck

0

Dependency Injection에 익숙하십니까?

아니요, 그렇다면 그 개념에 대해 배우는 것이 도움이 될 것입니다. 나는 마틴 파울러 (Martin Fowler)가 굿 어웨이 Inversion of Control Containers and the Dependency Injection pattern을 좋은 소개로 제공 할 것입니다.

DI (Dependency Injection)를 사용하면 모든 종류의 클래스를 생성 할 수있는 DI 컨테이너 개체를 사용할 수 있습니다. 그런 다음 객체가 DI 컨테이너를 사용하여 클래스를 인스턴스화하고 클래스가 예상 클래스의 인스턴스를 생성하는지 테스트하기 위해 DI 컨테이너를 조롱합니다.

0

의존성 주입 또는 제어 반전.

또는 작성한 모든 객체에 대해 추상 팩토리 디자인 패턴을 사용하십시오. 단위 테스트 모드에있을 때, 무엇을 만들고 있는지 알려주는 테스트 팩토리를 삽입 한 다음 테스트 팩토리에 어썰트 코드를 포함시켜 결과를 확인하십시오 (제어 반전).

가능한 한 깨끗한 코드로 유지하려면 내부 보호 된 인터페이스를 만들고 내부 클래스로 프로덕션 코드로 인터페이스 (사용자의 팩토리)를 구현하십시오. 기본 팩토리에 초기화 된 인터페이스의 정적 변수 유형을 추가하십시오. 팩토리에 대한 정적 설정기를 추가하면 완료됩니다.

테스트 코드 (동일한 패키지에 있어야하며 그렇지 않으면 내부 인터페이스가 공용이어야 함)에서 어설 션 코드 및 테스트 코드로 익명 또는 내부 클래스를 만듭니다. 그런 다음 테스트에서 대상 클래스를 초기화하고 테스트 팩토리를 할당 (삽입) 한 다음 대상 클래스의 메서드를 실행합니다.

1

아아, 나는 틀린 질문을하는 것이 유죄라고 생각합니다. "새로운 ClassAWrapper는()"라는 경우 객체 toWrap가에서 얻을 열심히했기 때문에

public Wrapper wrapObject(Object toWrap) { 
    if(toWrap instanceof ClassA) { 
     return new Wrapper((ClassA) toWrap); 
    } else if (toWrap instanceof ClassB) { 
     return new Wrapper((ClassB) toWrap); 
    } // etc 

    else { 
     return null; 
    } 
} 

내가 어떻게 찾을 질문을했다 :

내가 시험려고 간단한 공장 같은 것을 보았다 격리 된 테스트. 그리고 wrapper (심지어 호출 될 수있는 경우)는 다른 클래스를 사용하여 다른 객체를 래핑하기 때문에 이상하게 보입니다. 다른 생성자를 사용합니다 [1]. 나는 조금 더 나은 질문을하면 신속하게 답변을 얻었을 것입니다 :

"다른 테스트 방법에서 테스트중인 인스턴스와 일치 시키려면 Object toWrap을 조롱하고 결과 래퍼를 검사해야합니다. 올바른 유형을 찾을 수있는 객체가 반환됩니다 ... 그리고 다른 인스턴스를 만들기 위해 전 세계를 조롱 할 필요가없는 행운이 있기를 바랍니다. "

이제는 즉각적인 문제, 감사합니다!

[1]이 리팩토링할지 여부의 질문 개방이 작업을 수행 할 수

관련 문제