java Spring Mockito @injectmocks 不起作用
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/41584454/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Spring Mockito @injectmocks not working
提问by Victor Tsai
Hi I'm using Mockito to test my Spring project, but the @InjectMocks
seems not working in injecting a mocked service into another Spring service(bean).
嗨,我正在使用 Mockito 来测试我的 Spring 项目,但@InjectMocks
似乎无法将模拟服务注入另一个 Spring 服务(bean)。
Here is my Spring service that I want to test:
这是我要测试的 Spring 服务:
@Service
public class CreateMailboxService {
@Autowired UserInfoService mUserInfoService; // this should be mocked
@Autowired LogicService mLogicService; // this should be autowired by Spring
public void createMailbox() {
// do mething
System.out.println("test 2: " + mUserInfoService.getData());
}
}
And below is the service that I want to mock:
下面是我要模拟的服务:
@Service
public class UserInfoService {
public String getData() {
return "original text";
}
}
My test code is here:
我的测试代码在这里:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "file:src/main/webapp/WEB-INF/spring/root-context.xml" })
public class CreateMailboxServiceMockTest {
@Mock
UserInfoService mUserInfoService;
@InjectMocks
@Autowired
CreateMailboxService mCreateMailboxService;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
}
@Test
public void deleteWithPermission() {
when(mUserInfoService.getData()).thenReturn("mocked text");
System.out.println("test 1: " + mUserInfoService.getData());
mCreateMailboxService.createMailbox();
}
}
but the result would like
但结果是
test 1: mocked text
test 2: original text // I want this be "mocked text", too
it seems that the CreateMailboxServicedidn't get the mocked UserInfoServicebut using Spring's autowired bean.
Why is my @InjectMocks
not working?
似乎CreateMailboxService没有得到模拟的UserInfoService而是使用 Spring 的自动装配 bean。为什么我的@InjectMocks
不工作?
Regards
问候
采纳答案by alayor
You can create package
level setter for mUserInfoService
in CreateMailboxService
class.
您可以在课堂上创建package
水平设置器。mUserInfoService
CreateMailboxService
@Service
public class CreateMailboxService {
@Autowired UserInfoService mUserInfoService; // this should be mocked
@Autowired LogicService mLogicService; // this should be autowired by Spring
public void createMailbox() {
// do mething
System.out.println("test 2: " + mUserInfoService.getData());
}
void setUserInfoService(UserInfoService mUserInfoService) {
this.mUserInfoService = mUserInfoService;
}
}
Then, you can inject that mock in the test using the setter.
然后,您可以使用 setter 在测试中注入该模拟。
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "file:src/main/webapp/WEB-INF/spring/root-context.xml" })
public class CreateMailboxServiceMockTest {
@Mock
UserInfoService mUserInfoService;
CreateMailboxService mCreateMailboxService;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
mCreateMailboxService = new CreateMailboxService();
mCreateMailboxService.setUserInfoService(mUserInfoService);
}
...
}
This way you can avoid problems with @InjectMocks
and Spring annotations.
通过这种方式,您可以避免@InjectMocks
Spring 注释的问题。
回答by Andreas
For those who stumbles on this thread and are running with JUnit 5 you need to replace the
@RunWith(SpringJUnit4ClassRunner.class)
对于那些偶然发现此线程并使用 JUnit 5 运行的人,您需要替换
@RunWith(SpringJUnit4ClassRunner.class)
with
和
@ExtendWith(MockitoExtension.class)
@RunWith(JUnitPlatform.class)
@ExtendWith(MockitoExtension.class)
@RunWith(JUnitPlatform.class)
Further reading here https://www.baeldung.com/mockito-junit-5-extension. Unfortunately there is no hint when executing the test cases with junit 5 using the old annotation.
在此处进一步阅读https://www.baeldung.com/mockito-junit-5-extension。不幸的是,在使用旧注释使用 junit 5 执行测试用例时没有提示。
回答by Derek Nash
If you are trying to use the @Mock annotation for a test that relies directly on Spring injection, you may need to replace @Mockwith @MockBean @Inject(both annotations), and @InjectMockswith @Inject. Using your example:
如果您尝试将 @Mock 批注用于直接依赖 Spring 注入的测试,则可能需要将@Mock替换为@MockBean @Inject(两个批注),将@InjectMocks 替换为@Inject。使用您的示例:
@MockBean
@Inject
UserInfoService mUserInfoService;
@Inject
CreateMailboxService mCreateMailboxService;
回答by Raj Shukla
For those who are running with JUnit 5you need to replace the @RunWith(SpringJUnit4ClassRunner.class)
with @ExtendWith(MockitoExtension.class)
.
For further reading https://www.baeldung.com/mockito-junit-5-extension
对于那些谁与运行JUnit的5您需要更换@RunWith(SpringJUnit4ClassRunner.class)
有 @ExtendWith(MockitoExtension.class)
。
进一步阅读https://www.baeldung.com/mockito-junit-5-extension
回答by Seba Cervantes
I had a pretty similar situation. I am writing it down just in case any reader is going through the same. In my case I found that the problem was that I was setting my injected variable as final
in the local class.
我有一个非常相似的情况。我把它写下来,以防万一读者遇到同样的情况。就我而言,我发现问题在于我将注入的变量设置为final
在本地类中。
Following your example, I had things like this:
按照你的例子,我有这样的事情:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "file:src/main/webapp/WEB-INF/spring/root-context.xml" })
public class CreateMailboxServiceMockTest {
@Mock
UserInfoService mUserInfoService;
@InjectMocks
CreateMailboxService mCreateMailboxService = new CreateMailboxService(mUserInfoService);
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
}
@Test
public void deleteWithPermission() {
...
}
}
But in this class I had it like this:
但在这门课上,我是这样的:
@Service
public class CreateMailboxService {
private final UserInfoService mUserInfoService; // it is NOT injecting Mocks just because it is final! (all ok with private)
private final LogicService mLogicService; // it is NOT injecting Mocks just because it is final! (all ok with private)
@Autowired
public CreateMailboxService(UserInfoService mUserInfoService, LogicService mLogicService) {
this.mUserInfoService = mUserInfoService;
this.mLogicService = mLogicService;
}
public void createMailbox() {
...
}
}
Just deleting the final
condition, @InjectMocks
problem was solved.
只要删除final
条件,@InjectMocks
问题就解决了。
回答by jAvA
there is no need of @Autowired annotation when you inject in the test class. And use the mock for the method to get your mocked response as the way you did for UserInfoService.That will be something like below. Mockito.when(mCreateMailboxService. getData()).thenReturn("my response");
在测试类中注入时不需要 @Autowired 注释。并使用该方法的模拟来获取模拟响应,就像您为 UserInfoService 所做的那样。这将类似于下面的内容。Mockito.when(mCreateMailboxService.getData()).thenReturn("我的回复");