在服务测试中使用真实组件
Use a real component in a service test
我正在测试具有自动装配帮助程序组件的服务。该组件具有自动装配的回购协议。
在我的测试中,我想使用那个组件助手,而不是模拟。我想为此模拟回购协议。
但我无法让它发挥作用。
我测试的服务:
@Service
public class ServiceImpl{
@Autowired
private Helper helper;
}
具有自动装配 repo
的助手 class
@Component
public class Helper {
@Autowired
private Repository repo;
}
我的测试应该是这样的
@ExtendWith(MockitoExtension.class)
public class ServiceImplTest {
ServiceImpl service;
@Mock
private Repository repoMock;
@InjectMocks
private Helper helper;
}
我想更好地重构整个事情,但不幸的是,这是不可能的...
欢迎任何帮助。
如果 Repository
是一个接口(而不是具体的 class),您可以尝试以下操作:
@ExtendWith(MockitoExtension.class)
public class ServiceImplTest {
@Spy
@InjectMocks
ServiceImpl service = new ServiceImpl();
@Mock
private Repository repoMock;
@InjectMocks
private Helper helper;
}
我更喜欢构造函数注入而不是字段注入。 (阅读更多 )
在这种情况下,您 类 看起来像这样:
@Component
public class Helper {
@Autowired
public Helper(Repository repo) {
this.repo = repo;
}
}
@Service
public class ServiceImpl{
@Autowired
public ServiceImpl(Helper helper) {
this.helper = helper;
}
}
通过这种方式,您可以轻松地使用模拟 Repository
对象创建真实的 Helper
对象:
ServiceImpl service;
private Helper helper;
@Mock
private Repository repoMock;
@BeforeEach
void init() {
helper = new Helper(repoMock);
service = new ServiceImpl(helper);
}
尝试为您的测试加载配置,优先考虑模拟存储库 已测试:
@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。尽快切换到构造函数依赖注入。
另请参阅:
我终于找到了解决办法,谢谢你的帮助。
@ExtendWith(MockitoExtension.class)
public class ServiceImplTest {
@InjectMocks
ServiceImpl service
@Spy
@InjectMocks
private Helper helper;
@Mock
private Repository repoMock;
@InjectMocks
private Helper helper;
}
这样,模拟的 repo 被注入到间谍助手中,而助手可以被注入到服务中。
@Spy 对象实际上是实例化的,所以如果你不存根它的任何方法,你将得到一个 "real" 对象。
在这里,mocked repo 被注入到 helper 中,helper 被注入到服务中。
我正在测试具有自动装配帮助程序组件的服务。该组件具有自动装配的回购协议。
在我的测试中,我想使用那个组件助手,而不是模拟。我想为此模拟回购协议。
但我无法让它发挥作用。
我测试的服务:
@Service
public class ServiceImpl{
@Autowired
private Helper helper;
}
具有自动装配 repo
的助手 class@Component
public class Helper {
@Autowired
private Repository repo;
}
我的测试应该是这样的
@ExtendWith(MockitoExtension.class)
public class ServiceImplTest {
ServiceImpl service;
@Mock
private Repository repoMock;
@InjectMocks
private Helper helper;
}
我想更好地重构整个事情,但不幸的是,这是不可能的...
欢迎任何帮助。
如果 Repository
是一个接口(而不是具体的 class),您可以尝试以下操作:
@ExtendWith(MockitoExtension.class)
public class ServiceImplTest {
@Spy
@InjectMocks
ServiceImpl service = new ServiceImpl();
@Mock
private Repository repoMock;
@InjectMocks
private Helper helper;
}
我更喜欢构造函数注入而不是字段注入。 (阅读更多
在这种情况下,您 类 看起来像这样:
@Component
public class Helper {
@Autowired
public Helper(Repository repo) {
this.repo = repo;
}
}
@Service
public class ServiceImpl{
@Autowired
public ServiceImpl(Helper helper) {
this.helper = helper;
}
}
通过这种方式,您可以轻松地使用模拟 Repository
对象创建真实的 Helper
对象:
ServiceImpl service;
private Helper helper;
@Mock
private Repository repoMock;
@BeforeEach
void init() {
helper = new Helper(repoMock);
service = new ServiceImpl(helper);
}
尝试为您的测试加载配置,优先考虑模拟存储库 已测试:
@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。尽快切换到构造函数依赖注入。
另请参阅:
我终于找到了解决办法,谢谢你的帮助。
@ExtendWith(MockitoExtension.class)
public class ServiceImplTest {
@InjectMocks
ServiceImpl service
@Spy
@InjectMocks
private Helper helper;
@Mock
private Repository repoMock;
@InjectMocks
private Helper helper;
}
这样,模拟的 repo 被注入到间谍助手中,而助手可以被注入到服务中。 @Spy 对象实际上是实例化的,所以如果你不存根它的任何方法,你将得到一个 "real" 对象。
在这里,mocked repo 被注入到 helper 中,helper 被注入到服务中。