将Guice和JMock一起使用的最佳方法是什么?

Yis*_*hai 7 java guice jmock

我已经开始使用吉斯做一个项目的一些依赖注入,主要是因为我需要注入嘲笑(使用JMock的目前)层从单元测试,这使得人工注射非常尴尬了.

我的问题是引入模拟的最佳方法是什么?我目前所拥有的是在单元测试中创建一个满足依赖关系的新模块,并将它们绑定到如下所示的提供者:

public class JMockProvider<T> implements Provider<T> {
    private T mock;

    public JMockProvider(T mock) {
        this.mock = mock;
    }

    public T get() {
        return mock;
    }
}
Run Code Online (Sandbox Code Playgroud)

在构造函数中传递mock,因此JMock设置可能如下所示:

    final CommunicationQueue queue = context.mock(CommunicationQueue.class);
    final TransactionRollBack trans = context.mock(TransactionRollBack.class);
    Injector injector = Guice.createInjector(new AbstractModule() {
        @Override
        protected void configure() {
            bind(CommunicationQueue.class).toProvider(new JMockProvider<QuickBooksCommunicationQueue>(queue));
            bind(TransactionRollBack.class).toProvider(new JMockProvider<TransactionRollBack>(trans));
        }
    });
    context.checking(new Expectations() {{
        oneOf(queue).retrieve(with(any(int.class)));
        will(returnValue(null));
        never(trans);
    }});
    injector.getInstance(RunResponse.class).processResponseImpl(-1);
Run Code Online (Sandbox Code Playgroud)

有没有更好的办法?我知道,AtUnit试图解决这个问题,虽然我失去了它是如何自动奇迹般地注入这是本地创建像上面的一个模拟,但是我正在寻找无论是令人信服的理由,AtUnit是正确的答案在这里(其他而不是在不改变测试的情况下改变DI和模拟框架的能力,或者是否有更好的解决方案来手动完成.

gpa*_*ara 12

你不应该通过DI框架注入模拟.我非常成功地使用Guice和JMock,我的单元测试没有引用与Guice相关的任何内容.我只使用模拟并传入null适用的地方.

DI将允许注入和构造当前类的依赖项,因此如果要添加一个模拟的类(有效地停止依赖图),您只需要将其传入.Misko Hevery在其中一个Google Tech中声明谈论单元测试应该充斥着new's和null's因为它们的范围局限于单个单元测试方法 - 我必须同意他的看法.

是否有理由需要在测试中使用Guice,即它们是否不是功能/集成测试?

如果排除喷射器,测试是否会起作用?难道你不能将你的测试重构为:

final CommunicationQueue queue = context.mock(CommunicationQueue.class);
final TransactionRollBack trans = context.mock(TransactionRollBack.class);

context.checking(new Expectations() {{
    oneOf(queue).retrieve(with(any(int.class)));
    will(returnValue(null));
    never(trans);
}});

RunResponse r = new RunResponse(queue, trans); // depending on the order
r.processResponseImpl(-1);
Run Code Online (Sandbox Code Playgroud)

  • 我知道了.没有什么可以阻止你在测试中使用Guice,但如果可能的话,我建议尝试避免它(除非你在功能/集成级别进行测试)问题是你违反了得墨忒耳法则.您当前的类应该只担心它的直接依赖性,并且不应考虑传递依赖性.在当前类依赖项的单元测试中,您执行的操作完全相同,并且只考虑直接依赖项.这样的模式使您的代码更清晰,更友好的DI :) (4认同)