簡體   English   中英

Junit:使用@Autowired專用字段進行測試服務

[英]Junit: testing service with private @Autowired fields

我過去幾周一直在進行Junit測試,因此,作為一名初級程序員,我的經驗非常有限。 在測試了項目中較簡單的服務類之后,現在我陷入了困境。
問題是我無法將一些private final someRepository注入到我正在測試的服務類的構造函數中,即:

@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()使用SpringRunner.class返回null 當我使用MockitoJUnitRunner.class運行時, someService構造函數將引發構造函數錯誤: someRepository is NULL
我嘗試了多種方法(嘗試了@Spy@MockBeanMockito().doReturn...語法等),但這是我遇到的兩個錯誤。 我很確定這是正確使用Mocking框架的問題。
如果您需要其他代碼段或詳細信息,請提供。

原因是由於@InjectMocks批注,Mockito試圖構造對象。

SpringRunner因為這不是彈簧測試。 如果您真的想要一個特殊的跑步者,可以選擇MockitoJUnitRunner

您可以簡單地在Before方法中初始化Mockito批注,然后使用提供模擬依賴項的構造函數創建服務實例。

public class SomeServiceTest {
    @Mock
    private SomeRepository someRepository;

    private SomeService someService;

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

    /* ... */
}

你可以使用ReflectionTestUtil Spring提供從測試類注射SomeRepository的模擬。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM