2011-11-04 2 views
0

JUnit 테스트에서 Spring DAO에서 최대 절전 모드 템플릿을 변경하려고합니다. 방법 -이 DAO는 런타임시에 싸서 다중 포장 된 객체에서 반사

  • 이 Mockitos 스파이()에 의해에 spyed됩니다 있도록
    1. 는 @Transactional 주석이다. 그래서 DAO는 그 스파이가 두 번째로 싸울 것입니다.

    이제 DAO에는 @Transactional에서 하나, 스파이에서 하나의 래핑 개체가 있습니다. 그 래퍼 중 먼저 생성 된 래퍼를 알 수 없기 때문에 반영을 통해 DAO에서 최대 절전 모드 템플릿을 설정할 수 없습니다.

    어떻게 이중 랩핑 DAO에서 템플릿을 설정할 수 있습니까?

    [편집]

    일부 출처 : 테스트 클래스에서

    /** 
    * This class gets wrapped by a proxy object because of @Transactional. 
    */ 
    @Transactional 
    public class MyDao implements SomeDaoInterface { ... } 
    

    :

    public class MyTestClass { 
    @Autowired 
    private MyDao myDao; 
    
    @Test 
    public void myTestMethod() throws Exception { 
        final MyDao daoSpy = spy(myDao); // Dao gets wrapped with second wrapper 
    
        final Field field = MyDao.class.getDeclaredField("template"); 
        field.setAccessible(true); 
        field.set(daoSpy, mySpecialMockedTemplate); // ERROR: want to inject the template but 
                   // dont know in which wrapper 
    } 
    } 
    
  • +0

    안녕하세요, 샘플 코드를 추가 할 수 있습니까? – Brice

    답변

    2

    전화 대신 필드를 액세스하는 세터 방법.

    +0

    setter를 사용하면 문제가 해결되지 않습니다. @Autowired 때문에 Spring에서 dao를 래핑합니다. 세터는 dao가 아닌이 랩에 주어진 속성을 설정합니다. – Steven

    2

    반사 코드가 잘못 나온 것 같습니다. 대신이 문을 사용하지만 테스트 코드를 찾고

    field.set(daoSpy, mySpecialMockedTemplate); 
    

    , 당신이 MyDao 인스턴스를 생성하기 위해 스프링을 사용하는 것 같다. 템플릿을 설정하기 위해 리플렉션을 사용하는 것이 이상하게 보입니다. 왜 스프링에서 설정하지 않으시겠습니까? 또는 실제 설정기를 사용 하시겠습니까? 또는 필드를 보호하여 단위 테스트 만 액세스 할 수 있습니다.

    EDIT : 주사에 대해서는 테스트에서 DAO 인스턴스를 만들고 specialMockedTemplate을 Mockito가 삽입 할 수 있습니다.

    @RunWith(MockitoJUnitRunner.class) 
    public class MyTestClass { 
        @InjectMocks private MyDao dao; 
    
        @Mock SpecialTemplate specialTemplate; 
    
        @Test void dao_should_call_the_template_with_parameter_A_and_B() { 
         // given 
    
         // when 
         dao.someCall("A", "B"); 
    
         // then 
         verify(specialTemplate).someCallWith("A", "B"); 
        } 
    } 
    

    몇 가지 경고가 있지만 가능한 경우 (스파이를 사용하여) 부분적 조롱을 피하십시오. 자신이 소유하지 않은 종류의 모킹을 피하십시오.이 부분을 읽어야합니다. blog post entry 이것은 왜 나쁜 생각입니까?

    +0

    PowerMockito가 또 다른 옵션으로 여기에서 도움이 될 수 있습니다. – AHungerArtist

    +0

    PowerMock lib는 테스트가 어려운 코드에 적합하지만 Powermock을 테스트해야하는 디자인 코드는 사용하지 않는 것이 좋습니다. 코드를 해킹하고 유지 관리하기가 어렵습니다. – Brice

    +0

    맞습니다. 잘못된 반사 코드를 게시합니다. setter를 사용하면 문제가 해결되지 않습니다. @Autowired 때문에 Spring은 dao를 래핑합니다. 세터는 dao가 아닌이 랩에 주어진 속성을 설정합니다. 실제로 Spring에서 설정하는 것이 이것을 수행하는 유일한 방법 인 것 같습니다. 또는 DAO는 autowired가 아닌 instanciated 얻을 수 있습니다. – Steven