Junit:使用私有@Autowired 字段测试服务
Junit: testing service with private @Autowired fields
过去几周我一直在做 Junit 测试,所以我作为初级程序员的经验相当有限。在项目中测试了更简单的服务classes,现在卡住了。
问题是我无法将一些 private final someRepository
注入到我正在测试的服务 class 的构造函数中,即:
@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()
return null
和 SpringRunner.class
时。当我 运行 和 MockitoJUnitRunner.class
时,someService
构造函数抛出一个构造函数错误:someRepository is NULL
我尝试了多种方法(尝试了 @Spy
、@MockBean
、Mockito().doReturn...
语法等),但这是我遇到的两个错误。我很确定这是正确使用 Mocking 框架的问题。
如果您需要其他片段或详细信息,我会很乐意提供。
您可以使用 Spring 提供的 ReflectionTestUtil 从测试 class.
中注入 SomeRepository 的模拟
例如;
ReflectionTestUtils.setField(someService, "someRepository", mock(SomeRepository.class));
原因是 Mockito 试图构造对象,因为 @InjectMocks
注释。
SpringRunner
不是必需的,因为这不是 spring 测试。如果你真的想要一个特别的跑步者,你可以去MockitoJUnitRunner
。
您可以简单地在 Before
方法中初始化 Mockito 注释,然后使用提供模拟依赖项的构造函数创建您的服务实例。
public class SomeServiceTest {
@Mock
private SomeRepository someRepository;
private SomeService someService;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
someService = new SomeService(someRepository);
}
/* ... */
}
过去几周我一直在做 Junit 测试,所以我作为初级程序员的经验相当有限。在项目中测试了更简单的服务classes,现在卡住了。
问题是我无法将一些 private final someRepository
注入到我正在测试的服务 class 的构造函数中,即:
@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()
return null
和 SpringRunner.class
时。当我 运行 和 MockitoJUnitRunner.class
时,someService
构造函数抛出一个构造函数错误:someRepository is NULL
我尝试了多种方法(尝试了 @Spy
、@MockBean
、Mockito().doReturn...
语法等),但这是我遇到的两个错误。我很确定这是正确使用 Mocking 框架的问题。
如果您需要其他片段或详细信息,我会很乐意提供。
您可以使用 Spring 提供的 ReflectionTestUtil 从测试 class.
中注入 SomeRepository 的模拟例如;
ReflectionTestUtils.setField(someService, "someRepository", mock(SomeRepository.class));
原因是 Mockito 试图构造对象,因为 @InjectMocks
注释。
SpringRunner
不是必需的,因为这不是 spring 测试。如果你真的想要一个特别的跑步者,你可以去MockitoJUnitRunner
。
您可以简单地在 Before
方法中初始化 Mockito 注释,然后使用提供模拟依赖项的构造函数创建您的服务实例。
public class SomeServiceTest {
@Mock
private SomeRepository someRepository;
private SomeService someService;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
someService = new SomeService(someRepository);
}
/* ... */
}