2013-08-16 9 views
9

この質問は前の質問Specify Custom Application Contextの続きです。jersey-spring3を使用してJerseyTestコンテナからマネージドBeanを取得します。

ジャージースプリングを使用して、ジャージースプリングを使用してジャージースプリングからジャージー2.xにデータサービスの一部を移行しています。

JerseyTestから継承したテストクラスがいくつかあります。これらのクラスの中には、web.xmlファイルで指定されていないカスタムapplicationContext.xmlファイルを使用するものがあります。

オブジェクトをモックする目的で、ジャージーリソースのいくつかのコンポーネントをモックアウトします。我々は

<bean id="mockBean" class="org.easymock.EasyMock" 
    factory-method="createStrictMock" autowire="byName"> 
    <constructor-arg index="0" value="com.xxx.xxx.ClassToMock" /> 
</bean> 

することにより、アプリケーションのコンテキストファイル内のオブジェクトをモックと同じジャージー2で達成することができますどのように

ClassToMock obj = (ClassToMock)ContextLoader 
    .getCurrentWebApplicationContext() 
    .getAutowireCapableBeanFactory() 
    .getBean("mockBean"); 

を次のようにこれらの嘲笑のインスタンスを取得することができジャージー1.xでは

。 xジャージースプリング3を使って?

API docsuser guides、およびsourcesのうちのいくつかをコーディネートしましたが、回答が見つかりませんでした。

ありがとうございます。

EDIT:

私たちは、JAX-RSリソースの内部嘲笑豆を使用することになります。私たちのリソースには@Autowiredというサービスインターフェイスがあります。

@Path(ProductResource.RESOURCE_PATH) 
@Component 
@Scope("prototype") 
public class ProductResource 
extends GenericResource<Product, BaseModel> { 

    /* 
    * Members 
    */ 

    public static final String RESOURCE_PATH = "product/"; 

    @Autowired 
    protected ProductService productService; 

    ... 

私たちはこれらのサービスに期待を寄せています。

<bean id="productService" class="org.easymock.EasyMock" 
    factory-method="createStrictMock"> 
    <constructor-arg index="0" 
     value="com.xxx.xxx.service.ProductService" /> 
</bean> 
+0

例としてこれを説明できますか? JAX-RSリソースの中にあるのですか?正確に 'WebApplicationContext'が必要か、あるいは' ApplicationContext'で十分ですか? –

+0

'WebApplicationContext'または' ApplicationContext'のどちらでも問題ありません。 JAX-RSリソースに注入されたBeanへのポインタを提供します。 –

答えて

8

注:私は春の専門家ではないと私は、これは推奨されるアプローチではなく、回避策であると考えています。うまくいけば、誰かがより良い解決策を思いつきます。

あなたはジャージー2.xのランタイムユニット/ E2Eテストのためニュージャージーテストフレームワーク(JerseyTest)を使用する場合、サーブレットコンテナの外側に初期化デフォルトであるため、ContextLoader#getCurrentWebApplicationContext()を呼び出してApplicationContextインスタンスを得ることができません。

あなたはテストパッケージにApplicationContextAwareインタフェースを実装することによりApplicationContextを得るために、少しの回避策を使用する必要がある。この場合:あなたは、このクラスを持っていたら、それを言及するのを忘れないでください

public class ApplicationContextUtils implements ApplicationContextAware { 

    private static ApplicationContext applicationContext; 

    public static ApplicationContext getApplicationContext() { 
     return applicationContext; 
    } 

    @Override 
    public void setApplicationContext(final ApplicationContext applicationContext) throws BeansException { 
     ApplicationContextUtils.applicationContext = applicationContext; 
    } 
} 

アプリケーションのコンテキスト記述子に:

... 
<bean class="org.glassfish.jersey.examples.helloworld.spring.ApplicationContextUtils" /> 
... 

そして、あなたはあなたのテストでそれを使用することができます。

public class JerseySpringResourceTest extends JerseyTest { 

    // ... Configure ... 

    @Before 
    public void mockUp() throws Exception { 
     // ApplicationContext is ready in your @Before methods ... 
     assertThat(ApplicationContextUtils.getApplicationContext(), notNullValue()); 
    } 

    @Test 
    public void testJerseyResource() { 
     // ... as well as in your test methods. 
     assertThat(ApplicationContextUtils.getApplicationContext(), notNullValue()); 
    } 
} 

注:あなたはサーブレットコンテナにアプリケーションをデプロイし、それに対するあなたの(JerseyTest)テストを実行し、ユーザーガイド(特にExternal container節)でJersey Test Framework章に相談してください。ジャージー2.Xユーザーの場合

+0

フィードバックいただきありがとうございます。できるだけ早く試してみます。ただ一つの質問。 'setApplicationContext'では、' this.applicationContext = applicationContext; 'ではなく、' ApplicationContextUtils.applicationContext = applicationContext; 'と書いておいてください。 –

+0

うん、固定。ありがとう。 –

+1

ApplicationContextUtilsで '@Component'アノテーションを使用することもできます(コンポーネントスキャンされたパッケージ内にあることを保証する)ので、Beanを明示的に宣言する必要はありません。 –

1

は、ここに私のために働いたものだ:

public class AccountResourceTest extends JerseyTest { 

    private ApplicationContext context; 

    private BeanA beanA; 

    private BeanB beanB; 

    public AccountResourceTest() throws TestContainerException { 
     super(); 

     beanA = context.getBean(BeanA.class); 
     beanB = context.getBean(BeanB.class); 
    } 

    @Override 
    protected Application configure() { 
     context = new AnnotationConfigApplicationContext(SpringConfiguration.class); 
     final ResourceConfig config = new JerseyConfiguration().property("contextConfig", context); 
     return config; 
    } 

    @Override 
    protected void configureClient(final ClientConfig config) { 
     config.register(JacksonJsonProvider.class); 
    } 

    ... 
} 

これは私が私のジャージー試験にJavaConfigを使用することができ、そして同様のコンテキストでBeanにアクセス。ジャージーのバージョン2.4.xのではhttp://geowarin.github.io/spring-boot/jersey/2014/01/31/a-simple-spring-boot-and-jersey-application.html

1

、クラスJerseyConfigurationはもう存在していないとcontextConfig性質を理解していないResourceConfigに置き換えられました。ここで私はアイデアを得た場所へのリンクがあります。ここに私の解決策があります:

package ch.vd.test; 

import java.net.URI; 

import javax.ws.rs.core.Application; 

import org.glassfish.hk2.api.ServiceLocator; 
import org.glassfish.jersey.server.ApplicationHandler; 
import org.glassfish.jersey.server.ResourceConfig; 
import org.glassfish.jersey.test.JerseyTest; 
import org.glassfish.jersey.test.grizzly.GrizzlyTestContainerFactory; 
import org.glassfish.jersey.test.spi.TestContainer; 
import org.glassfish.jersey.test.spi.TestContainerException; 
import org.glassfish.jersey.test.spi.TestContainerFactory; 
import org.junit.Test; 
import org.springframework.context.ApplicationContext; 

public class ExampleTest extends JerseyTest { 

    private ServiceLocator serviceLocator; 

    @Override 
    public void setUp() throws Exception { 
     super.setUp(); 
     final ApplicationContext context = serviceLocator.getService(ApplicationContext.class, "SpringContext"); 
     final Object bean = context.getBean("someBean"); 
    } 

    @Override 
    protected Application configure() { 
     final ResourceConfig config = new ResourceConfig(RestResources.class); 
     config.property("contextConfigLocation", "classpath:example-context.xml"); 
     return config; 
    } 

    @Override 
    protected TestContainerFactory getTestContainerFactory() throws TestContainerException { 
     return new GrizzlyTestContainerFactory() { 
      @Override 
      public TestContainer create(URI uri, ApplicationHandler appHandler) throws IllegalArgumentException { 
       serviceLocator = appHandler.getServiceLocator(); 
       return super.create(uri, appHandler); 
      } 
     }; 
    } 

    @Test 
    public void testStuff() throws Exception { 
     ... 
    } 
} 
3

あなたがそれに対して反対意見がなければ、あなたのテストクラスをジャージーコンテキストに注入することができます。例えば

@Autowired注釈があなたのために働くことの後

@Override 
protected Application configure() { 
    final TestJerseyApplication application = new TestJerseyApplication(); 

    final Map<String, Object> properties = new HashMap<>(); 
    properties.put("contextConfigLocation", "classpath:test-spring-context.xml"); 
    application.setProperties(properties); 

    application.register(this); 
    return application; 
} 

+0

ああ、デフォルトの 'applicationContext.xml'の代わりに、 "contextConfigLocation"で検索するカスタムSpringコンテキストファイルをJerseyに伝えることができます。 – jediz

関連する問題