我正在尝试使用Junit,mockito和PowerMock来创建单元测试
我的问题是我试图模拟的一个类是返回一个空对象
这是我的代码
@RunWith(PowerMockRunner.class)
@PrepareForTest(ClientBuilder.class)
public class SolrPopulateApplicationTest {
@Mock
ClientConfig clientConfig;
@Mock
Client client;
@Mock
Response response;
@Mock
JerseyClient jerseyClient;
@Mock (answer = Answers.RETURNS_DEEP_STUBS)
JerseyWebTarget jerseyWebTarget;
@InjectMocks
@Autowired
SolrPopulateApplication solrPopulateApplication;
@Test
public void indexTest(){
PowerMockito.mockStatic(ClientBuilder.class);
ClientBuilder cli = Mockito.mock(ClientBuilder.class);
when(ClientBuilder.newClient(Matchers.any())).thenReturn(client);
when(jerseyClient.target(Matchers.anyString())).thenReturn(jerseyWebTarget);
when(jerseyWebTarget.path(Matchers.anyString())
.queryParam(Matchers.anyString(),Matchers.anyString())
.request(Matchers.anyString())
.header(Matchers.anyString(),Matchers.anyString())
.post(Matchers.any())).thenReturn(response);
boolean var = solrPopulateApplication.index("test","test");
}
}
如果在设置完所有模拟之后放置调试断点,我将得到以下内容
client = {Client$$EnhancerByMockitoWithCGLIB$$7f4c6946@1705} "client"
response = {Response$$EnhancerByMockitoWithCGLIB$$b85fdf42@1704} "response"
jerseyWebTarget = {JerseyWebTarget$$EnhancerByMockitoWithCGLIB$$7d7091b9@1703} "null"
solrPopulateApplication = {SolrPopulateApplication@1702}
jerseyClient = {JerseyClient$$EnhancerByMockitoWithCGLIB$$6437ba91@1701} "jerseyClient"
cli = {ClientBuilder$$EnhancerByMockitoWithCGLIB$$20196b6d@1700} "Mock for ClientBuilder, hashCode: 2080643905"
this = {SolrPopulateApplicationTest@1695}
你可以看到jerseyWebClient是一个NULL,当我尝试运行测试时,这会导致nullpointerexception。
我尝试从@mock语句中删除(answer = Answers.RETURNS_DEEP_STUBS),这没什么区别。
正在测试的方法实际上调用了一个实现JerseyWebTarget类的接口。我已经确定我试图通过在JerseyWebTarget类中放置一个调试器来模拟正确的类,以确保它停止在通过接口调用的方法上。
任何人都可以告诉我为什么会这样,以及如何解决它。
答案 0 :(得分:2)
假设您使用的是Mockito @Mock
注释...
要使用Mockito @Mock
注释,您必须在每次测试之前执行特定的代码行。您可以在设置方法中执行此操作:
@Before
public void init() {
MockitoAnnotations.initMocks(this);
}
您还必须@RunWith(MockitoJUnitRunner.class)
,但在使用PowerMockRunner
时,可能没有必要这样做。
我建议你尽量避免使用PowerMock,或者至少让你的模拟器与Mockito合作,然后继续用PowerMock编写测试。我引用PowerMock wiki中的以下内容:
请注意,PowerMock主要面向具有单元测试专业知识的人员。把它放在初级开发人员手中可能会带来更多弊大于利。
除非在此有必要使用PowerMock的特定原因,否则请避免使用。例如,您可以将JerseyWebTarget
传递到SolrPopulateApplication
的构造函数中,而不是直接调用您正在测试的类中的ClientBuilder
。
此外,PowerMock和Mockito可能并不总能在一起玩得很好。例如,请参阅this bug。