我尝试运行此测试:
@Mock IRoutingObjHttpClient routingClientMock;
@Mock IRoutingResponseRepository routingResponseRepositoryMock;
@Test
public void testSendRoutingRequest() throws Exception {
CompleteRoutingResponse completeRoutingResponse = new CompleteRoutingResponse();
completeRoutingResponse.regression_latencyMillis = 500L;
Mockito.when(routingClientMock.sendRoutingRequest(any(RoutingRequest.class))).thenReturn(completeRoutingResponse);
RoutingObjHttpClientWithReRun routingObjHttpClientWithReRun = new RoutingObjHttpClientWithReRun
(routingClientMock, routingResponseRepositoryMock);
...
}
但我得到空指针异常:
Mockito.when(routingClientMock.
我错过了什么?
当您想使用 @Mock
注释时,您应该使用 MockitoJUnitRunner
@RunWith(MockitoJUnitRunner.class)
public class MockitoTest {
@Mock
private IRoutingObjHttpClient routingClientMock;
@Test
public void testSendRoutingRequest() throws Exception {
// ...
}
}
另请参阅本教程。
如果您使用的是 Junit5,则可能会出现同样的问题,因为不再有"@RunWith"注释。
在这种情况下,您应该使用以下方法注释您的类:
@ExtendWith(MockitoExtension.class)
public class MyTestClass {
...
您还应该导入到您的依赖项中(Maven - pom.xml):
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
<version>${mockito.version}</version>
<scope>test</scope>
</dependency>
有三个选项来激活@Mock
注释:MockitoRule、MockitoJUnitRunner、MockitoAnnotations.initMocks(this)。恕我直言,使用 MockitoRule
是最好的,因为它可以让您仍然选择另一个跑步者,例如 Parameterized
.
使用模拟规则
public class MockitoTest {
@Mock
private IRoutingObjHttpClient routingClientMock;
@Rule
public MockitoRule rule = MockitoJUnit.rule();
@Test
public void testSendRoutingRequest() throws Exception {
// ...
}
}
使用 MockitoJUnitRunner
@RunWith(MockitoJUnitRunner.class)
public class MockitoTest {
@Mock
private IRoutingObjHttpClient routingClientMock;
@Test
public void testSendRoutingRequest() throws Exception {
// ...
}
}
显式调用 MockitoAnnotations.initMocks(this)。
这可以在 qn @Before
方法、您自己的运行器或自己的规则中完成。
public class MockitoTest {
@Mock
private IRoutingObjHttpClient routingClientMock;
@Before
public void createMocks() {
MockitoAnnotations.initMocks(this);
}
@Test
public void testSendRoutingRequest() throws Exception {
// ...
}
}
如果将junit.jupiter
与测试类的@ExtendWith(MockitoExtension.class)
一起使用,但模拟为空,请确保从 导入@Test
注释
import org.junit.jupiter.api.Test;
而不是org.junit.Test;
是什么为我解决了这个问题(上面的答案和我自己的补充):
-
@Before
方法中的MockitoAnnotations.initMocks(this);
- 测试类必须是公开的
- 测试方法必须是公开的
-
import org.junit.Test;
而不是import org.junit.jupiter.api.Test;
在 Intellij 中执行命令 + N --> Test...
时,它会生成(至少作为默认值)一些在我的情况下不起作用的样板。
,即使添加了@RunWith(MockitoJUnitRunner.class)
它也无法正常工作。
事实证明,我犯了一个愚蠢的错误@Test
,
import org.junit.jupiter.api.Test;
而不是
import org.junit.Test;
纠正后,它奏效了!
将@ExtendWith(MockitoExtension.class)注释添加到测试类中,它应该可以工作,因为您使用的是Junit 5+版本。如果您使用的是旧版本的Junit,请使用@RunWith(MockitoJUnitRunner.class)注释。
- 您应该在课堂上使用
@RunWith(SpringJUnit4ClassRunner.class)
- 您必须在@Before方法中调用
MockitoAnnotations.initMocks(this);
这也可能是导入问题,因此请确保您具有适当的导入包。
例如,"org.easymock"包也有一个名为@Mock的注释,当然,它不适用于Mockito特定的设置。
我遇到了一个问题,我声明@Mock MyClass myClass,然后试图在我的@BeforeAll注释方法中模拟一种行为:
@Mock
private MyClass myClass;
...
@BeforeAll
public void init()
{
...
Mockito.when(myClass.something()).thenReturn("Not found")
...
}
显然 init() 是在 myClass 的模拟初始化之前执行的,所以 myClass == 在 init() 中为 null。
解决方案是将注释从@BeforeAll更改为@BeforeEach。
对我来说,当我添加:
- 在班级级别:
@RunWith(MockitoJUnitRunner.class).
- 课堂内:
@Before
public void createMocks() {
MockitoAnnotations.initMocks(this);
}
尝试检查您调用的方法是否是最终方法。
Mockito不能模拟最终的方法。 https://github.com/mockito/mockito/wiki/FAQ
Junit 5 with InjectMocks。基于上述建议 https://stackoverflow.com/a/55616702/2643815
@ExtendWith(MockitoExtension.class)
public class MyClientTest {
@Mock
Environment environment;
@Mock
ClassCreator classCreator;
@InjectMocks
MyClient myClient;
@Test
public void mytest() {
myClient = new MyClient(environment, classCreator);
}
}
注释添加到类中:
@RunWith(MockitoJUnitRunner.class)
修改 Mockito 的版本解决了这个问题。
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>2.23.4</version>
<scope>test</scope>
</dependency>
我遇到了同样的问题,但我发现将我的测试(最初是为 JUnit 3 编写的,并使用传统的 setUp()
和tearDown()
方法)更新到 JUnit 4 和现代注释夹具方法有效。
此外,如果您使用的是规则:
@Rule public MockitoRule rule = MockitoJUnit.rule();
确保规则也在公共类上,否则您将收到以下消息:
How did getFields return a field we couldn't access?
在对我有用的评论中找到了这个解决方案。对您正在创建的所有模拟执行此操作。
您需要实例化 routetingClientMock,例如
routingClientMock = Mockito.mock(RoutingObjHtttpClient.class);
<</div>
div class="one_answers"> 我的问题是我试图模拟一个在我的服务中是最终的对象。只需要删除最终,它就起作用了。
我们的应用程序使用JUNIT5
,发生了同样的问题。我用@InjectMocks
替换了@Mock
- 然后问题解决了
如果您也在使用 PowerMock,那么
@RunWith(MockitoJUnitRunner.class)
可以替换为
@RunWith(PowerMockRunner.class)
这将激活您的@Mocks
并启用 PowerMock 功能。