2016-09-19 118 views
2

我试图使用JUnit,的Mockito和PowerMock创建单元测试我试图使用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 = {[email protected]} "client" 
response = {[email protected]} "response" 
jerseyWebTarget = {[email protected]} "null" 
solrPopulateApplication = {[email protected]} 
jerseyClient = {[email protected]} "jerseyClient" 
cli = {[email protected]} "Mock for ClientBuilder, hashCode: 2080643905" 
this = {[email protected]} 

正如你所看到的jerseyWebClient是一个NULL,这导致nullpointerexception当我尝试运行测试。

我试图从@mock语句中删除(answer = Answers.RETURNS_DEEP_STUBS),这没有什么区别。

被测试的方法实际上调用了实现JerseyWebTarget类的接口。我已经确定我试图通过在JerseyWebTarget类中放置一个调试器来确保它停止在通过接口调用的方法上来模拟正确的类。

谁能告诉我为什么会发生这种情况,以及如何解决这个问题。

+0

您还应该包含您的导入语句,以便您的示例已完成。我对PowerMock并不熟悉,并且据我所知,PowerMock和Mockito都可以包含模拟注释。 – tonicsoft

回答

1

假设你正在使用的Mockito @Mock注释...

要使用的Mockito @Mock注解,你必须每次测试之前执行一个特定的代码行。您可以在设置方法做到这一点:

@Before 
public void init() { 
    MockitoAnnotations.initMocks(this); 
} 

你还必须@RunWith(MockitoJUnitRunner.class)但由于您使用的是PowerMockRunner那么这可能不是必要的。

我会建议你尽可能避免使用PowerMock,或者至少在使用PowerMock编写测试之前让你的模拟与Mockito一起工作。我从PowerMock wiki引用以下内容:

请注意,PowerMock主要用于具有单元测试专业知识的人员。把它交给初级开发者可能会造成更多的伤害而不是好事。

除非在这里需要PowerMock的一个非常具体的原因,否则避免它。例如,您可以将JerseyWebTarget传递到您的SolrPopulateApplication的构造函数中,而不是直接调用您正在测试的课程中的ClientBuilder

此外,PowerMock和Mockito可能不会总是在一起玩。例如,请参见this bug

+0

被嘲笑的方法之一是静态的 是模拟静态方法所需的powermock吗? – lee

+0

PowerMock是模拟静态方法所必需的。我建议你应该避免嘲笑静态方法。相反,将静态方法调用包装在您创建的对象的实例方法中。这个实例方法现在可以在没有PowerMock的情况下被模拟。更好的是,不要在正在测试的类中调用方法 - 将方法的结果传递给类构造函数。 – tonicsoft