2010-12-02 11 views
8

Jersey ile başlıyorum ve TDD kullanarak freemarker ile çalışmaya başladım. Şablonlarım için ViewProcessor yapmak istiyorum, ancak sınıftaki sunucu içeriği bağlamında başarısızlığa uğramadım. İşte Jersey test çerçevesi kullanılırken sunucu içeriği enjeksiyonu başarısız oluyor

sınıf kodu:

@Provider 
public class myProcessor implements ViewProcessor<Template> { 

    [...] 

    @Context 
    public ServletContext myContext; 

    [...] 

freemarkerConfiguration.setTemplateLoader(
     new WebappTemplateLoader(myContext, 
      myContext.getInitParameter("freemarker.template.path"))); 

    [...] 
    } 

Ve burada bir test kodu:

public class myProcessorTest extends JerseyTest { 

    public static myProcessor mp; 

    public myProcessorTest() throws Exception{ 
     super(new WebAppDescriptor.Builder("com.domain").build()); 
    } 

    @Test 
    public void firstTest(){ 
     mp = new myProcessor(); 
     String path = new String("test.ftl"); 
     Template template = mp.resolve(path); 
     assertNotNull(template); 
    } 
} 

ben aşağıdaki gibi bağımlılıkları ile maven kullanın:

<dependency> 
    <groupId>com.sun.jersey.jersey-test-framework</groupId> 
    <artifactId>jersey-test-framework-grizzly</artifactId> 
    <version>1.5-SNAPSHOT</version> 
    <scope>test</scope> 
</dependency> 

Kodum iyi çalışır yerel iskele sunucusuna konuştuğumda. Testi çalıştırdığınızda myContextnull geçerli:: benim IDE kod test etmek istiyorsanız, o servlet içerik (@Context) enjekte etmekte başarısız Ben bir şey eksik düşünüyorum/

, ama değilim servlet dünyası ile yeni başlayanlar.

cevap

0

Bunu yapmanın birkaç yolu var. yapıcı çıkarın ve böyle bir yapılandırmak() yöntemini uygulamak:

public class myProcessorTest extends JerseyTest { 

    public static myProcessor mp; 

    @Override 
    protected AppDescriptor configure() { 
    return new WebAppDescriptor.Builder("com.domain") 
     .contextParam("contextConfigLocation", "classpath:/applicationContext.xml") 
     .contextPath("/").servletClass(SpringServlet.class) 
     .contextListenerClass(ContextLoaderListener.class) 
     .requestListenerClass(RequestContextListener.class) 
     .build(); 
    } 

veya alternatif bahar bağlamıyla testinizi açıklama edebilirsiniz: gerektirmez bu soruna bir çözüm

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration("classpath:applicationContext.xml") 
public class MyProcessorTest extends JerseyTest { 

    public static myProcessor mp; 
0

yoktur İlkbahar, varsayılan/standart Grizzy2 test çerçevesi sağlayıcısı kullandığınızı varsayar. this answer'a göre jersey-test-framework-provider-grizzly2 çerçeve sağlayıcısı, uygulama içeriğinin oluşturulmasında bir sunucu ortamı kullanmaz. Belirtileriniz, enjekte edilecek ServletContext örneğinden kaynaklanır.

Çözüm, ünite testleri için test kabını kendiniz sağlamanızdır. Bir Grizzy servlet kabı sağlamak için testini değiştirmek Sonra

<!--<dependency> 
    <groupId>org.glassfish.jersey.test-framework.providers</groupId> 
    <artifactId>jersey-test-framework-provider-grizzly2</artifactId> 
    <version>2.25</version> 
    <scope>test</scope> 
</dependency>--> 
<dependency> 
    <groupId>org.glassfish.jersey.test-framework</groupId> 
    <artifactId>jersey-test-framework-core</artifactId> 
    <version>2.25</version> 
</dependency> 
<dependency> 
    <groupId>org.glassfish.jersey.containers</groupId> 
    <artifactId>jersey-container-grizzly2-servlet</artifactId> 
    <version>2.25</version> 
</dependency> 

: Öncelikle, bağımlılıkları değiştirmek

@Override 
protected TestContainerFactory getTestContainerFactory() throws TestContainerException { 
    return (final URI baseUri, final DeploymentContext deploymentContext) -> 
    new TestContainer() { 
    private HttpServer server = null; 

    @Override 
    public ClientConfig getClientConfig() { 
     return null; 
    } 

    @Override 
    public URI getBaseUri() { 
     return baseUri; 
    } 

    @Override 
    public void start() { 
     try { 
     this.server = GrizzlyWebContainerFactory.create(baseUri, Collections 
      .singletonMap("jersey.config.server.provider.packages", "<your-package-name>")); 
     } catch (final ProcessingException | IOException cause) { 
     throw new TestContainerException(cause); 
     } 
    } 

    @Override 
    public void stop() { 
     this.server.shutdownNow(); 
    } 
    }; 
} 

Ben Birden birim testlerinde bu kullanacağız varsayalım, bu yüzden olabilir Bu ortak yapılandırma otomatik olarak gerçekleştirilebilmesi için JerseyTest'u genişletmek için bilge. Ayrıca, test kabı tarafından öykünmek/korumak istediğiniz herhangi bir işlevsellik olup olmadığını görmek için org.glassfish.jersey.test.grizzly.GrizzlyTestContainerFactory incelemeye değer olabilir. Sağlanan örnek, en azından bunun bir düzeltme olduğunu onaylamak için testinize bırakılabilir.

DÜZENLEME: Kendi uygulamamda, sunucu oluşturulurken hala bir ResourceConfig sağlama yeteneğini gerekli buldum. Diğer Jersey Test Framework kullanıcıları için bunun yaygın bir durum olabileceğinden şüpheleniyorum. Önerilen TestContainerFactory'un çalışma örneği aşağıdadır.

import java.io.IOException; 
import java.net.URI; 
import java.util.logging.Level; 
import java.util.logging.Logger; 

import javax.servlet.ServletContext; 
import javax.ws.rs.ProcessingException; 
import javax.ws.rs.core.UriBuilder; 

import org.glassfish.grizzly.http.server.HttpServer; 
import org.glassfish.grizzly.servlet.WebappContext; 
import org.glassfish.hk2.utilities.binding.AbstractBinder; 
import org.glassfish.jersey.client.ClientConfig; 
import org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory; 
import org.glassfish.jersey.test.DeploymentContext; 
import org.glassfish.jersey.test.spi.TestContainer; 
import org.glassfish.jersey.test.spi.TestContainerException; 
import org.glassfish.jersey.test.spi.TestContainerFactory; 
import org.glassfish.jersey.test.spi.TestHelper; 


public class RestTestContainerFactory implements TestContainerFactory {  
    public static class RestTestContainer implements TestContainer { 
    private static final Logger LOGGER = Logger.getLogger(RestTestContainer.class.getName()); 

    private URI baseUri = null; 
    private final HttpServer server; 

    public RestTestContainer(final URI baseUri, final DeploymentContext context) { 
     this.baseUri = UriBuilder.fromUri(baseUri).path(context.getContextPath()).build(); 
     if(LOGGER.isLoggable(Level.INFO)) { 
     LOGGER.info("Creating RestRestContainer configured at the base URI "+TestHelper.zeroPortToAvailablePort(baseUri)); 
     } 

     try { 
     final WebappContext webContext = new WebappContext("TestContext", context.getContextPath()); 
     context.getResourceConfig() 
       .register(new AbstractBinder() { 
       @Override 
       protected void configure() { 
        bind(webContext).to(ServletContext.class); 
       } 
       }); 
     this.server = GrizzlyHttpServerFactory.createHttpServer(this.baseUri, context.getResourceConfig(), false); 
     webContext.deploy(this.server); 

     } catch (final ProcessingException cause) { 
     throw new TestContainerException(cause); 
     } 
    } 

    @Override 
    public ClientConfig getClientConfig() { 
     return null; 
    } 

    @Override 
    public URI getBaseUri() { 
     return baseUri; 
    } 

    @Override 
    public void start() { 
     if(server.isStarted()) { 
     LOGGER.warning("Ignoring start request - RestTestContainer is already started"); 
     } else { 
     LOGGER.fine("Starting RestTestContainer..."); 
     try { 
      server.start(); 
      if(baseUri.getPort() == 0) { 
      baseUri = UriBuilder.fromUri(baseUri) 
       .port(server.getListener("grizzly").getPort()) 
       .build(); 
      LOGGER.info("Started GrizzlyTestContainer at the base URI "+baseUri); 
      } 
     } 
     catch(final ProcessingException | IOException cause) { 
      throw new TestContainerException(cause); 
     } 
     } 
    } 

    @Override 
    public void stop() { 
     if(server.isStarted()) { 
     LOGGER.fine("Stopping RestTestContainer..."); 
     server.shutdownNow(); 
     } else { 
     LOGGER.warning("Ignoring stop request - RestTestContainer is already stopped"); 
     } 
    } 
    } 

    @Override 
    public TestContainer create(final URI baseUri, final DeploymentContext context) { 
    return new RestTestContainer(baseUri,context); 
    } 
} 

Frustratingly, boz en GrizzlyWebContainerFactory bir servlet bağlam sağlamak, ancak bir kaynak yapılandırma ile yapılandırmayacaktır. Tersine, GrizzlyHttpServerFactory bir uygulamayı ResourceConfig ile yapılandırır, ancak bir web içeriği sağlamaz.

Biz WebappContext (ServletContext genişletir) manuel olarak oluşturmak yapılandırmaya ve ardından bir AbstractBinder vasıtasıyla kaynak yapılandırma içine enjekte ederek bu çalışabilirsiniz.