2017-04-11 289 views
0

我一直在做的Junit測試服務測試在過去的幾個星期,所以我的經驗,作爲一個初級程序員是相當有限的。在測試了項目中更容易的服務類之後,現在我陷入了困境。
的問題是,我不能注入一些private final someRepository到服務類的構造函數,我的測試,即:
Junit的:與私人領域@Autowired

@RunWith(SpringRunner.class) 
public class SomeServiceTest { 
    @Mock 
    private SomeRepository someRepository; 
    @InjectMocks 
    private SomeService someService; 

    @Test 
    public void testMyFunc() { 
     SomeOtherDto param = new SomeOtherDto(); 
     param.setVar1(...); 
     param.setVar2(...); 
     Mockito.when(someRepository.getIt()).thenReturn(-1L); 
     Mockito.when(someService.myPrivBoolBuilder(param,-1L))                      
              .thenReturn(new BooleanBuilder()); 
     Pageable pageable = null; 
     Page<SomeDto> result = someService.myFunc(param, pageable); 
     assertEquals(expResult, 
    } 
    /* ... */ 
} 

和服務我測試:

@Service 
@Transactional 
public class SomeService implements someAbstractService { 
    private final CustomMapper customMapper 
    private final SomeRepository someRepository; 
    private final SomeOtherRepository someOtherRepository; 

    @Autowired 
    public SomeService(final CustomMapper customMapper, final SomeRepository someRepository, 
         final SomeOtherRepository someOtherRepository, etc) 
    { /* ... */ } 

    public Page<SomeDto> myFunc(final SomeOtherDto param, final Pageable pageable) { 
     final BooleanBuilder predicate = myPrivBoolBuilder(param, 
              someOtherRepository.getId()); 
     return someRepository.findAll(predicare, pageable).map(obj -> { 
              return customMapper.map(obj) }); 
    } 

    public BooleanBuilder myPrivBoolBuilder(final SomeOtherDto param, final Long id) { 
     BooleanBuilder predicate = new BooleanBuilder(); 
     final QSomeRepository qSomeRepository = QSomeRepository.someRepository; 
     final QSomeOtherRepository qSomeOtherRepository = QSomeOtherRepository.someOtherRepository(); 
     predicate.and(qSomeRepository.someField.someOtherField.goe(param.getX())); 
     predicate.and(qSomeRepository.someField2.someOtherField2.isNotNull())); 
     predicate.and(qSomeOtherRepository.someField.someOtherField.id.eq(id() 
      .or(qSomeOtherRepository.someField.someOtherField.id.in(...)))); 
     return predicate;   
    } 
    /* ... */  
} 

我的問題是,當我運行測試someOtherRepository.getId()回報nullSpringRunner.class。當我與MockitoJUnitRunner.class運行someService構造函數拋出一個構造錯誤:someRepository is NULL
我已經嘗試了多種方法(試@Spy@MockBeanMockito().doReturn...語法等),但這些都是兩個錯誤,我得到。我很確定這是正確使用Mocking框架的問題。
如果你需要其他的片段或細節,我會很樂意提供。

回答

1

原因是由於@InjectMocks註釋Mockito試圖構造對象。

SpringRunner沒有必要,因爲這不是一個春季測試。如果你真的想要一個特別的跑步者,你可以去MockitoJUnitRunner

你可以簡單地初始化註釋的Mockito在Before方法,然後用構造提供嘲笑的依賴關係創建服務實例。

public class SomeServiceTest { 
    @Mock 
    private SomeRepository someRepository; 

    private SomeService someService; 

    @Before 
    public void setUp() { 
     MockitoAnnotations.initMocks(this); 
     someService = new SomeService(someRepository); 
    } 

    /* ... */ 
} 
+0

我都試過了,但現在的問題是這一行:'Mockito.when(someService.myPrivBoolBuilder(PARAM,-1L)) .thenReturn(新BooleanBuilder());' 運行時錯誤是' when()需要一個必須是'模擬方法調用'的參數。 –

+0

您正在試圖嘲諷真實對象(someService)上的方法調用。你必須嘲笑someRepository。 – galovics

+0

你說得對。 有什麼方法(像'@ Spy',而且還注入那個討厭的'SomeRepository')與我可以模擬該函數調用? –

-1

您可以使用Spring提供的ReflectionTestUtil爲測試類注入SomeRepository模擬。

例如; ReflectionTestUtils.setField(someService, "someRepository", mock(SomeRepository.class));