Yot*_*oen 6 setter spring constructor code-injection mockito
我有一个类通过构造函数注入成员,其他通过setter注入.我似乎无法让Mockito注入二传手.注入的构造函数被模拟得很好,但是setter的返回为null.当我将setter-ed成员翻转到构造函数注入时,一切都很顺利.这是原始的生产代码:
@Autowired
private BetRepository betRepository;
public void setBetRepository(BetRepository betRepository) {
this.betRepository = betRepository;
}
public TournamentScoringCache(TournamentScoringCacheInitializer cacheInitializer,
ScoringEngineInitializer scoringEngineInitializer) {
tournamentUserStates = cacheInitializer.initCache();
scoringEngines = scoringEngineInitializer.initEngines();
}
public <T extends SideScore> void updateGameScore(Long tournamentId, Long gameId, MatchScore<T> score) {
Map<Long, UserTournamentState> userStates = tournamentUserStates.get(tournamentId);
ScoringEngine<?> scoringEngine = scoringEngines.get(tournamentId);
List<Bet> bets = betRepository.getBetsByGameId(gameId); //HERE IS WHERE I GET THE NPE
....
}
Run Code Online (Sandbox Code Playgroud)
测试代码:
@Mock
BetRepository betRepository;
@Mock
TournamentScoringCacheInitializer cacheInitializer;
@Mock
ScoringEngineInitializer engineInitializer;
@InjectMocks
private TournamentScoringCacheAndDB tournamentScoringCache;
@Test
public void testUpdateGameScore() {
....
when(cacheInitializer.initCache()).thenReturn(utss);
when(betRepository.getBetsByGameId(1L)).thenReturn(createBets());
when(engineInitializer.initEngines()).thenReturn(createEngines());
when(engine.getBetScore(bet1, score)).thenReturn(betScore);
when(engine.getBetScore(bet2, score)).thenReturn(betScore2);
tournamentScoringCache.updateGameScore(tournamentId, gameId, score);
....
}
Run Code Online (Sandbox Code Playgroud)
有任何想法吗?
谢谢!
Daw*_*ica 16
是的,@ InjectMocks注释使得Mockito EITHER进行构造函数注入,或者setter/field注入,但是从不这两个.选择的规则非常复杂,这也是我尽量避免使用@InjectMocks的原因之一.
总而言之,Mockito FIRST从类中的那些中选择一个构造函数,然后分析该构造函数是否可用于构造函数注入.它选择的那个将永远是具有最多参数的那个.如果有多个构造函数具有相同数量的参数,则未定义哪个将被选择.
如果CHOSEN构造函数的一个或多个参数的类型是基本类型,或最终类或私有类,则不会使用构造函数注入.即使有其他构造函数可以使用.
如果未使用构造函数注入,或者唯一的构造函数是默认构造函数,则将使用setter/field injection.但是setter/field注入永远不会与构造函数注入一起使用.
尽管强烈建议使用构造函数注入,并且强烈建议不要使用混合注入方法,但我遇到了无法重构的此类。要解决该问题,请调用initMocksexplicitly。例如:
@InjectMocks
private ThingWithMixedDependencies thing;
@Mock
private FieldInjected secondDependency;
@BeforeEach
void setUp() {
// This cannot be a mocked field or else it will reinitialise thing.
ConstructorInjected firstDependency = Mockito.mock(ConstructorInjected.class);
thing = new ThingWithMixedDependencies(firstDependency);
MockitoAnnotations.initMocks(this);
}
@Test
void checkDependencies() {
assertThat(thing.getFirstDependency(), is(notNullValue()));
assertThat(thing.getSecondDependency(), is(notNullValue()));
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
16518 次 |
| 最近记录: |