java - 我正在尝试使用 Junit、mockito 和 PowerMock 创建单元测试

标签 java unit-testing 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 = {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,当我尝试运行测试时,这会导致空指针异常。

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

被测试的方法实际上调用了一个实现 JerseyWebTarget 类的接口(interface)。我已确保尝试通过在 JerseyWebTarget 类中放置一个调试器来模拟正确的类,以确保其停止在通过接口(interface)调用的方法上。

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

最佳答案

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

要使用 Mockito @Mock 注释,您必须在每次测试之前执行特定的代码行。您可以在设置方法中执行此操作:

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

您还必须@RunWith(MockitoJUnitRunner.class),但由于您使用的是PowerMockRunner,因此这可能不是必需的。

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

Please note that PowerMock is mainly intended for people with expert knowledge in unit testing. Putting it in the hands of junior developers may cause more harm than good.

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

此外,PowerMock 和 Mockito 可能并不总是能够很好地协同工作。例如,参见this bug .

关于java - 我正在尝试使用 Junit、mockito 和 PowerMock 创建单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39569676/

相关文章:

spring - Spring MVC 应用程序测试中的 ContextConfiguration

java - 使用 RecyclerView 制作类似目录的布局

javascript - 模拟 net.Socket 进行单元测试

unit-testing - 为测试而设计或停止为测试而设计

java - 每次运行 Junit 测试时实体管理器都为空

android - 无法在 Android JUnit 项目上进行 Ant 运行测试

java - Selenium 点击 javascript 链接

java - 测试 Spring Boot RestTemplate 客户端的 JSON 映射

java - 在 gwt.xml 中设置语言环境不起作用

单元测试 spring 服务类中的 java.lang.NullPointerException