【问题标题】:Use Guice to create components to use with ThreadWeaver使用 Guice 创建与 ThreadWeaver 一起使用的组件
【发布时间】:2015-12-29 00:55:59
【问题描述】:

我一直在处理的应用程序变得越来越复杂,以至于我在并发方面一遍又一遍地遇到相同的问题。解决相同的问题并且没有任何回归测试不再有意义。

那时我发现了 ThreadWeaver。对于我编写的一些简单的并发案例来说,这真的很棒,但是当我尝试用我的生产代码做一些更复杂的案例时,我开始感到沮丧。具体来说,当使用 Guice 注入组件时。

我有点难以理解 ThreadWeaver 运行测试的方式的含义,并在 wiki 文档中查找有关 Guice 或 DI 的任何提及,但没有运气。

Guice 与 ThreadWeaver 兼容吗?

这是我的测试

@Test
public void concurrency_test() {
    AnnotatedTestRunner runner = new AnnotatedTestRunner();
    runner.runTests(OPYLWeaverImpl.class, OPYLSurrogateTranscodingService.class);
}

这是我的测试实现

public class OPYLWeaverImpl extends WeaverFixtureBase {

@Inject private TaskExecutor                 taskExecutor;
@Inject private Serializer                   serializer;
@Inject private CountingObjectFileMarshaller liveFileMarshaller;
@Inject private GraphModel                   graphModel;
@Inject private CountingModelUpdaterService  updaterService;
@Inject private BabelCompiler                babelCompiler;
@Inject private EventBus                     eventBus;

OPYLSurrogateTranscodingService service;

private Path testPath;

@ThreadedBefore
public void before() {
    service = new OPYLSurrogateTranscodingService(eventBus, taskExecutor, serializer, liveFileMarshaller,
            () -> new OPYLSurrogateTranscodingService.Importer(graphModel, babelCompiler, updaterService, eventBus),
            () -> new OPYLSurrogateTranscodingService.Validator(eventBus, babelCompiler),
            () -> new OPYLSurrogateTranscodingService.Exporter(graphModel, updaterService));
}

@ThreadedMain
public void mainThread() {
    testPath = FilePathOf.OASIS.resolve("Samples/fake-powershell-unit-test.opyl");
    service.applyToExistingGraphModel(testPath);
}

@ThreadedSecondary
public void secondaryThread() {

}

@ThreadedAfter
public void after() {

}

还有WeaverFixtureBase

public class WeaverFixtureBase {
@Inject protected CountingEventBus eventBus;

@Before public final void setupComponents() {
    Injector injector = Guice.createInjector(new WeaverTestingEnvironmentModule(CommonSerializationBootstrapper.class));
    injector.getMembersInjector((Class) this.getClass()).injectMembers(this);
}
private class WeaverTestingEnvironmentModule extends AbstractModule {

    private final Class<? extends SerializationBootstrapper> serializationBootstrapper;

    public WeaverTestingEnvironmentModule(Class<? extends SerializationBootstrapper> serializationConfiguration) {
        serializationBootstrapper = serializationConfiguration;
    }

    @Override protected void configure() {
        bind(TaskExecutor.class).to(FakeSerialTaskExecutor.class);
        bind(SerializationBootstrapper.class).to(serializationBootstrapper);
        bind(ModelUpdaterService.class).toInstance(new CountingModelUpdaterService());
        bindFactory(StaticSerializationConfiguration.Factory.class);

        CountingEventBus localEventBus = new CountingEventBus();

        bind(Key.get(EventBus.class, Bindings.GlobalEventBus.class)).toInstance(localEventBus);
        bind(Key.get(EventBus.class, Bindings.LocalEventBus.class)).toInstance(localEventBus);
        bind(CountingEventBus.class).toInstance(localEventBus);
        bind(EventBus.class).toInstance(localEventBus);

    }
    @Provides
    @Singleton
    public GraphModel getGraphModel(EventBus eventBus, Serializer serializer) {
        return MockitoUtilities.createMockAsInterceptorTo(new GraphModel(eventBus, serializer));
    }
}

但是当类加载器加载OPYLWeaverImpl 时,Guice 的东西都没有发生,我得到一大堆空值。

我觉得这是“缺少一些非常简单”的场景之一。对不起,如果是!

【问题讨论】:

  • 您确定 ThreadWeaver 尊重您的 @Before 方法吗?据我所知,ThreadWeaver 中没有@Before,JUnit 仅尊重 TestCase 实现本身上的 @Before@After 之类的注释——而不是由测试用例创建或使用的类。也许最好把它放在@ThreadedBefore 方法中?

标签: java unit-testing testing guice thread-weaver


【解决方案1】:

上面的评论是对的。 Thread-weaver 与 JUnit 完全无关。 Thread weaver 是它自己的运行器,它根据自己的注释执行测试用例。您不得在 Thread Weaver 测试中使用任何特定于 JUnit 的注释。

除此之外,Thread Weaver 不需要任何与特定框架的兼容性。它操作 Java 字节码并使用 aeperate 类加载器加载操作过的代码。

最后,没有任何辅助测试的 Thread Weaver 测试没有任何意义。线程编织器通过交错单独的执行路径来工作。如果没有第二个线程,Thread Weaver 只会单步执行一个线程,而不会添加任何值。

【讨论】:

  • 谢谢你们俩!
  • 我意识到第二个线程对于一个理智的测试很重要,我只是想确保在投入精力之前我能做到这一点。这很有意义,我最终只是设置了调用setupComponents()@ThreadedBefore 方法中,就像 Groostav 说的那样。我最终遇到了 javaFX 的另一个问题,我认为这是同一个问题,但是当我终于花时间查看堆栈跟踪时,我发现我已经走出了困境。谢谢您的帮助!看起来这毕竟是一件简单的事情。当我获得 15 个代表时,我一定会记得为你的答案投票!
猜你喜欢
  • 1970-01-01
  • 2015-01-01
  • 2017-01-09
  • 1970-01-01
  • 1970-01-01
  • 2022-03-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多