我正在测试具有自动连接的帮助程序组件的服务。该组件具有自动连接的存储库。
在测试中,我想使用该组件帮助程序,而不是模拟程序。我想为此模拟回购。
但是我无法使其正常工作。
我测试的服务
@Service
public class ServiceImpl{
@Autowired
private Helper helper;
}
具有自动回购链接的Helper类
@Component
public class Helper {
@Autowired
private Repository repo;
}
我的测试应该是这样
@ExtendWith(MockitoExtension.class)
public class ServiceImplTest {
ServiceImpl service;
@Mock
private Repository repoMock;
@InjectMocks
private Helper helper;
}
我想更好地重构整个事情,但是不幸的是,这不可能...
欢迎任何帮助。
答案 0 :(得分:2)
我更喜欢构造函数注入而不是字段注入。 (了解更多here)
在这种情况下,您的课程如下所示:
@Component
public class Helper {
@Autowired
public Helper(Repository repo) {
this.repo = repo;
}
}
@Service
public class ServiceImpl{
@Autowired
public ServiceImpl(Helper helper) {
this.helper = helper;
}
}
通过这种方式,您可以轻松地创建带有模拟Helper
对象的真实Repository
对象:
ServiceImpl service;
private Helper helper;
@Mock
private Repository repoMock;
@BeforeEach
void init() {
helper = new Helper(repoMock);
service = new ServiceImpl(helper);
}
答案 1 :(得分:2)
我终于找到了解决方案,谢谢您的帮助。
@ExtendWith(MockitoExtension.class)
public class ServiceImplTest {
@InjectMocks
ServiceImpl service
@Spy
@InjectMocks
private Helper helper;
@Mock
private Repository repoMock;
@InjectMocks
private Helper helper;
}
这样,模拟回购被注入到间谍助手中,而助手可以被注入服务中。 @Spy对象实际上是实例化的,因此,如果不使用它的任何方法,都会得到一个“真实”对象。
在这里,模拟回购被注入到助手中,而助手被注入到服务中。
答案 2 :(得分:0)
如果Repository
是接口(而不是具体的类),则可以尝试以下操作:
@ExtendWith(MockitoExtension.class)
public class ServiceImplTest {
@Spy
@InjectMocks
ServiceImpl service = new ServiceImpl();
@Mock
private Repository repoMock;
@InjectMocks
private Helper helper;
}
答案 3 :(得分:0)
尝试为测试加载配置,该配置优先于模拟仓库 Tested :
@RunWith(SpringRunner.class)
@SpringBootTest
public class SomeTest {
@Configuration
static class ContextConfiguration {
@Bean
public Helper helper() {
return new Helper();
}
@Bean
@Primary
public Repository repoMock() {
Repo repo = Mockito.mock(Repository.class);
Mockito.when(/* Mock your repo */);
return repo;
}
}
@Autowired
private Helper helper;
@Test
public void testMethod() {
// Your test goes here
}
}
无论如何,请记住该字段会自动装配is evil。尽快切换到构造函数依赖项注入。
另请参见: