dropwizard 中的单元测试视图 (sequel)

Unit testing views in dropwizard (sequel)

related post I am trying to test my resources in Dropwizard. The resources can both return json data and views. The latter work with freemarker templates. For testing paths which return views I extended the code of the dropwizard manual中提到的还要添加一个供应商:

@ClassRule
public static final ResourceTestRule resources = ResourceTestRule.builder()
        .addResource(new MyResource(myDAO)).addProvider(ViewMessageBodyWriter.class).build();

然而,结果是以下冗长的错误消息:

WARN  [2015-04-14 12:00:33,471] org.glassfish.jersey.internal.Errors: The following warnings have been detected: WARNING: HK2 service reification failed for [io.dropwizard.views.ViewMessageBodyWriter] with an exception:
MultiException stack 1 of 2
java.lang.NoSuchMethodException: Could not find a suitable constructor in io.dropwizard.views.ViewMessageBodyWriter class.
    at org.glassfish.jersey.internal.inject.JerseyClassAnalyzer.getConstructor(JerseyClassAnalyzer.java:189)
    at org.jvnet.hk2.internal.Utilities.getConstructor(Utilities.java:180)
    at org.jvnet.hk2.internal.ClazzCreator.initialize(ClazzCreator.java:129)
    at org.jvnet.hk2.internal.ClazzCreator.initialize(ClazzCreator.java:182)
    at org.jvnet.hk2.internal.SystemDescriptor.internalReify(SystemDescriptor.java:723)
    at org.jvnet.hk2.internal.SystemDescriptor.reify(SystemDescriptor.java:678)
    at org.jvnet.hk2.internal.ServiceLocatorImpl.reifyDescriptor(ServiceLocatorImpl.java:416)
    at org.jvnet.hk2.internal.ServiceLocatorImpl.narrow(ServiceLocatorImpl.java:2146)
    at org.jvnet.hk2.internal.ServiceLocatorImpl.access00(ServiceLocatorImpl.java:120)
    at org.jvnet.hk2.internal.ServiceLocatorImpl.compute(ServiceLocatorImpl.java:1281)
    at org.jvnet.hk2.internal.ServiceLocatorImpl.compute(ServiceLocatorImpl.java:1276)
    at org.glassfish.hk2.utilities.cache.LRUHybridCache$OriginThreadAwareFuture.call(LRUHybridCache.java:115)
    at org.glassfish.hk2.utilities.cache.LRUHybridCache$OriginThreadAwareFuture.call(LRUHybridCache.java:111)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at org.glassfish.hk2.utilities.cache.LRUHybridCache$OriginThreadAwareFuture.run(LRUHybridCache.java:173)
    at org.glassfish.hk2.utilities.cache.LRUHybridCache.compute(LRUHybridCache.java:292)
    at org.jvnet.hk2.internal.ServiceLocatorImpl.internalGetAllServiceHandles(ServiceLocatorImpl.java:1354)
    at org.jvnet.hk2.internal.ServiceLocatorImpl.getAllServiceHandles(ServiceLocatorImpl.java:1263)
    at org.jvnet.hk2.internal.ServiceLocatorImpl.getAllServiceHandles(ServiceLocatorImpl.java:1252)
    at org.glassfish.jersey.internal.inject.Providers.getServiceHandles(Providers.java:352)
    at org.glassfish.jersey.internal.inject.Providers.getCustomProviders(Providers.java:200)
    at org.glassfish.jersey.message.internal.MessageBodyFactory.<init>(MessageBodyFactory.java:247)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:408)
    at org.glassfish.hk2.utilities.reflection.ReflectionHelper.makeMe(ReflectionHelper.java:1129)
    at org.jvnet.hk2.internal.ClazzCreator.createMe(ClazzCreator.java:274)
    at org.jvnet.hk2.internal.ClazzCreator.create(ClazzCreator.java:368)
    at org.jvnet.hk2.internal.SystemDescriptor.create(SystemDescriptor.java:471)
    at org.jvnet.hk2.internal.SingletonContext.compute(SingletonContext.java:82)
    at org.jvnet.hk2.internal.SingletonContext.compute(SingletonContext.java:70)
    at org.glassfish.hk2.utilities.cache.Cache$OriginThreadAwareFuture.call(Cache.java:97)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at org.glassfish.hk2.utilities.cache.Cache$OriginThreadAwareFuture.run(Cache.java:154)
    at org.glassfish.hk2.utilities.cache.Cache.compute(Cache.java:199)
    at org.jvnet.hk2.internal.SingletonContext.findOrCreate(SingletonContext.java:121)
    at org.jvnet.hk2.internal.Utilities.createService(Utilities.java:2064)
    at org.jvnet.hk2.internal.ServiceLocatorImpl.internalGetService(ServiceLocatorImpl.java:711)
    at org.jvnet.hk2.internal.ServiceLocatorImpl.getService(ServiceLocatorImpl.java:653)
    at org.glassfish.jersey.server.model.ComponentModelValidator.<init>(ComponentModelValidator.java:97)
    at org.glassfish.jersey.server.ApplicationHandler.initialize(ApplicationHandler.java:496)
    at org.glassfish.jersey.server.ApplicationHandler.access0(ApplicationHandler.java:166)
    at org.glassfish.jersey.server.ApplicationHandler.run(ApplicationHandler.java:327)
    at org.glassfish.jersey.internal.Errors.call(Errors.java:289)
    at org.glassfish.jersey.internal.Errors.call(Errors.java:286)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
    at org.glassfish.jersey.internal.Errors.processWithException(Errors.java:286)
    at org.glassfish.jersey.server.ApplicationHandler.<init>(ApplicationHandler.java:324)
    at org.glassfish.jersey.server.ApplicationHandler.<init>(ApplicationHandler.java:277)
    at org.glassfish.jersey.test.inmemory.InMemoryTestContainerFactory$InMemoryTestContainer.<init>(InMemoryTestContainerFactory.java:77)
    at org.glassfish.jersey.test.inmemory.InMemoryTestContainerFactory$InMemoryTestContainer.<init>(InMemoryTestContainerFactory.java:63)
    at org.glassfish.jersey.test.inmemory.InMemoryTestContainerFactory.create(InMemoryTestContainerFactory.java:111)
    at org.glassfish.jersey.test.JerseyTest.createTestContainer(JerseyTest.java:277)
    at org.glassfish.jersey.test.JerseyTest.setUp(JerseyTest.java:609)
    at io.dropwizard.testing.junit.ResourceTestRule.evaluate(ResourceTestRule.java:157)
    at org.junit.rules.RunRules.evaluate(RunRules.java:20)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
MultiException stack 2 of 2
java.lang.IllegalArgumentException: Errors were discovered while reifying SystemDescriptor(
    implementation=io.dropwizard.views.ViewMessageBodyWriter
    contracts={javax.ws.rs.ext.MessageBodyWriter}
    scope=javax.inject.Singleton
    qualifiers={org.glassfish.jersey.internal.inject.Custom}
    descriptorType=CLASS
    descriptorVisibility=NORMAL
    metadata=
    rank=0
    loader=null
    proxiable=null
    proxyForSameScope=null
    analysisName=null
    id=118
    locatorId=1
    identityHashCode=389247924
    reified=false)
    at org.jvnet.hk2.internal.SystemDescriptor.reify(SystemDescriptor.java:689)
    at org.jvnet.hk2.internal.ServiceLocatorImpl.reifyDescriptor(ServiceLocatorImpl.java:416)
    at org.jvnet.hk2.internal.ServiceLocatorImpl.narrow(ServiceLocatorImpl.java:2146)
    at org.jvnet.hk2.internal.ServiceLocatorImpl.access00(ServiceLocatorImpl.java:120)
    at org.jvnet.hk2.internal.ServiceLocatorImpl.compute(ServiceLocatorImpl.java:1281)
    at org.jvnet.hk2.internal.ServiceLocatorImpl.compute(ServiceLocatorImpl.java:1276)
    at org.glassfish.hk2.utilities.cache.LRUHybridCache$OriginThreadAwareFuture.call(LRUHybridCache.java:115)
    at org.glassfish.hk2.utilities.cache.LRUHybridCache$OriginThreadAwareFuture.call(LRUHybridCache.java:111)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at org.glassfish.hk2.utilities.cache.LRUHybridCache$OriginThreadAwareFuture.run(LRUHybridCache.java:173)
    at org.glassfish.hk2.utilities.cache.LRUHybridCache.compute(LRUHybridCache.java:292)
    at org.jvnet.hk2.internal.ServiceLocatorImpl.internalGetAllServiceHandles(ServiceLocatorImpl.java:1354)
    at org.jvnet.hk2.internal.ServiceLocatorImpl.getAllServiceHandles(ServiceLocatorImpl.java:1263)
    at org.jvnet.hk2.internal.ServiceLocatorImpl.getAllServiceHandles(ServiceLocatorImpl.java:1252)
    at org.glassfish.jersey.internal.inject.Providers.getServiceHandles(Providers.java:352)
    at org.glassfish.jersey.internal.inject.Providers.getCustomProviders(Providers.java:200)
    at org.glassfish.jersey.message.internal.MessageBodyFactory.<init>(MessageBodyFactory.java:247)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:408)
    at org.glassfish.hk2.utilities.reflection.ReflectionHelper.makeMe(ReflectionHelper.java:1129)
    at org.jvnet.hk2.internal.ClazzCreator.createMe(ClazzCreator.java:274)
    at org.jvnet.hk2.internal.ClazzCreator.create(ClazzCreator.java:368)
    at org.jvnet.hk2.internal.SystemDescriptor.create(SystemDescriptor.java:471)
    at org.jvnet.hk2.internal.SingletonContext.compute(SingletonContext.java:82)
    at org.jvnet.hk2.internal.SingletonContext.compute(SingletonContext.java:70)
    at org.glassfish.hk2.utilities.cache.Cache$OriginThreadAwareFuture.call(Cache.java:97)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at org.glassfish.hk2.utilities.cache.Cache$OriginThreadAwareFuture.run(Cache.java:154)
    at org.glassfish.hk2.utilities.cache.Cache.compute(Cache.java:199)
    at org.jvnet.hk2.internal.SingletonContext.findOrCreate(SingletonContext.java:121)
    at org.jvnet.hk2.internal.Utilities.createService(Utilities.java:2064)
    at org.jvnet.hk2.internal.ServiceLocatorImpl.internalGetService(ServiceLocatorImpl.java:711)
    at org.jvnet.hk2.internal.ServiceLocatorImpl.getService(ServiceLocatorImpl.java:653)
    at org.glassfish.jersey.server.model.ComponentModelValidator.<init>(ComponentModelValidator.java:97)
    at org.glassfish.jersey.server.ApplicationHandler.initialize(ApplicationHandler.java:496)
    at org.glassfish.jersey.server.ApplicationHandler.access0(ApplicationHandler.java:166)
    at org.glassfish.jersey.server.ApplicationHandler.run(ApplicationHandler.java:327)
    at org.glassfish.jersey.internal.Errors.call(Errors.java:289)
    at org.glassfish.jersey.internal.Errors.call(Errors.java:286)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
    at org.glassfish.jersey.internal.Errors.processWithException(Errors.java:286)
    at org.glassfish.jersey.server.ApplicationHandler.<init>(ApplicationHandler.java:324)
    at org.glassfish.jersey.server.ApplicationHandler.<init>(ApplicationHandler.java:277)
    at org.glassfish.jersey.test.inmemory.InMemoryTestContainerFactory$InMemoryTestContainer.<init>(InMemoryTestContainerFactory.java:77)
    at org.glassfish.jersey.test.inmemory.InMemoryTestContainerFactory$InMemoryTestContainer.<init>(InMemoryTestContainerFactory.java:63)
    at org.glassfish.jersey.test.inmemory.InMemoryTestContainerFactory.create(InMemoryTestContainerFactory.java:111)
    at org.glassfish.jersey.test.JerseyTest.createTestContainer(JerseyTest.java:277)
    at org.glassfish.jersey.test.JerseyTest.setUp(JerseyTest.java:609)
    at io.dropwizard.testing.junit.ResourceTestRule.evaluate(ResourceTestRule.java:157)
    at org.junit.rules.RunRules.evaluate(RunRules.java:20)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)

看起来 HK2 无法通过仅给出 class 名称来实例化 ViewMessageBodyWriter;这意味着您需要自己创建它。 There is an example in dropwizard tests.

@ClassRule
public static final ResourceTestRule resources = ResourceTestRule.builder()
        .addResource(new MyResource(myDAO)).addProvider(new ViewMessageBodyWriter(new MetricRegistry(), ImmutableList.of(new FreemarkerViewRenderer()))).build();