使用带有Jersey Test + TestNg的powermock测试泽西休息服务时的问题

时间:2017-08-06 03:40:02

标签: testng powermock integration-testing jersey-test-framework

使用Jersey开发的休息服务。现在我想为这个Web服务编写一些集成测试,但由于并非所有从Web服务中使用的类都已经实现,我需要模拟它们中的一些。例如,我有以下类:

@echo off
setlocal EnableDelayedExpansion

for /L %%i in () do (
cls
echo/
echo ======
echo !DATE!
echo !TIME!
echo ======
timeout -t 1 > nul
)

然后我想测试与Jersey测试框架和TestNg + Powermock进行集成测试(使用构造函数模拟新对象)。

public class ServiceA {

public String getService() {
    return null;
}}

@Path("/myresource")
public class ResourceController {

@GET 
@Produces("text/plain")
public String getIt() {
    ServiceA a = new ServiceA();
    return a.getService();
}}

我的pom dependecy:

import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.test.JerseyTestNg;
import org.glassfish.jersey.test.jdkhttp.JdkHttpServerTestContainerFactory;
import org.glassfish.jersey.test.spi.TestContainerFactory;
import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PowerMockIgnore;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.testng.PowerMockObjectFactory;
import org.testng.Assert;
import org.testng.IObjectFactory;
import org.testng.annotations.ObjectFactory;
import org.testng.annotations.Test;

import javax.ws.rs.core.Application;
import javax.ws.rs.core.Response;

import static org.powermock.api.mockito.PowerMockito.mock;

    @PowerMockIgnore({"javax.ws.*", "org.glassfish.*"})
    @PrepareForTest({ResourceController.class})
        public class ResourceControllerTest extends JerseyTestNg.ContainerPerMethodTest {
       @Override
        protected Application configure() {
            return new ResourceConfig(ResourceController.class);
        }

        @Override
        protected TestContainerFactory getTestContainerFactory() {
            return new JdkHttpServerTestContainerFactory();
        }

@ObjectFactory
public IObjectFactory getObjectFactory() {
    return new PowerMockObjectFactory();
}


        @Test
        public void getItTest() {
            ServiceA mockA = mock(ServiceA.class);
            Mockito.when(mockA.getService()).thenReturn("service a");
  PowerMockito.whenNew(ServiceA.class).withAnyArguments().thenReturn(mockA);
            Response result = target("myresource").request().get();
            Assert.assertEquals(result.readEntity(String.class), "service a");
        }
    }

但是在运行时,getIt()方法中的实例ServiceA仍然作为新的ServiceA对象而不是mockA对象初始化。

有什么想法吗?谢谢,

如果添加PowerMockIgnore({“javax.ws。”,“org.glassfish。”}),请参阅以下异常:

    <dependency>
            <groupId>org.glassfish.jersey.test-framework.providers</groupId>
            <artifactId>jersey-test-framework-provider-inmemory</artifactId>
            <version>2.21</version>
        </dependency> 

        <dependency>
            <groupId>org.glassfish.jersey.test-framework</groupId>
            <artifactId>jersey-test-framework-core</artifactId>
            <version>2.21</version>
        </dependency>
        <dependency>
            <groupId>org.powermock</groupId>
            <artifactId>powermock-module-testng</artifactId>
            <version>1.7.0</version>
            <scope>test</scope>
        </dependency>
<dependency>
            <groupId>org.powermock</groupId>
            <artifactId>powermock-api-mockito</artifactId>
            <version>1.7.0</version>
            <scope>test</scope>
        </dependency>

1 个答案:

答案 0 :(得分:2)

我相信模拟可能不会发生,因为你没有将PowerMock的objectfactory实现连接到TestNG。

为了让powermockito和TestNG相互合作,您必须执行以下操作:

  • 配置TestNG以使用PowerMock对象工厂:您可以通过套件xml的object-factory标记中的属性<suite>或通过@org.testng.annotations.ObjectFactory带注释的方法执行此操作powermock通过扩展org.testng.IObjectFactory
  • 实现TestNG接口org.powermock.modules.testng.PowerMockObjectFactoryorg.powermock.modules.testng.PowerMockTestCase(或)
  • 使用@PrepareForTest准备静态类以供PowerMockit嘲笑

我无法在您的代码中找到使用PowerMock的对象工厂接线的任何参考。你可以尝试这样做,看看是否有帮助吗?

有关详细信息,请参阅here

<强>更新 为了超越ClassCastExceptions,您需要将以下注释添加到您的类中。

@org.powermock.core.classloader.annotations.PowerMockIgnore({"javax.ws.*", "org.glassfish.*"})

有关此问题的详细信息,请参阅this stackoverflow问题

PS:我假设您正在使用以下注释让powermock准备您的测试类进行模拟(您的问题中的示例显示其他内容)

@org.powermock.core.classloader.annotations.PrepareForTest({ResourceController.class})