测试中模拟 EJB 注入

发布于 2024-11-02 22:48:53 字数 339 浏览 2 评论 0原文

每当我想测试使用资源注入的类时,我最终都会包含一个仅在测试中使用的构造函数:

public class A {

    @EJB
    B b;

    // Used in tests to inject EJB mock
    protected A(B b) {
        this.b = b;
    }

    public A() {}

    // Method that I wish to test
    public void foo() {
        b.bar();
    }

}

是否有另一种模拟资源注入的方法,或者这是要遵循的正确模式?

Whenever I want to test a class which uses resource injection I end up including a constructor that will only be used within the test:

public class A {

    @EJB
    B b;

    // Used in tests to inject EJB mock
    protected A(B b) {
        this.b = b;
    }

    public A() {}

    // Method that I wish to test
    public void foo() {
        b.bar();
    }

}

Is there another way of mocking resource injection or this is the correct pattern to follow?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

血之狂魔 2024-11-09 22:48:53

您可以使用 easyloss 来达到此效果,它模拟 EJB 注入系统。

另一种方法是在测试中使用反射来设置字段,我有时使用这样的方法:

public static void setPrivateField(Class<? extends Object> instanceFieldClass, Object instance, String fieldName, Object fieldValue) throws Exception {
    Field setId = instanceFieldClass.getDeclaredField(fieldName);
    setId.setAccessible(true);
    setId.set(instance, fieldValue);
}

you could use easy gloss to that effect, it mocks the EJBs injection system.

another way is to set the field using reflexion in your tests, I sometime use something like this :

public static void setPrivateField(Class<? extends Object> instanceFieldClass, Object instance, String fieldName, Object fieldValue) throws Exception {
    Field setId = instanceFieldClass.getDeclaredField(fieldName);
    setId.setAccessible(true);
    setId.set(instance, fieldValue);
}
反目相谮 2024-11-09 22:48:53

Eliocs,

如果在接口处输入 B 那么你就不会“仅仅”为测试用例做它;你会允许“B 的行为”的任何替代实现,即使还没有想到它/它们的需要。

是的,基本上这是唯一要遵循的模式(据我所知)...所以(无论正确还是错误)你也可以充分利用它;-)

干杯。基思.

Eliocs,

If type B where an interface then you wouldn't "just" bo doing it for test-cases; you'd be allowing for any alternative implementations of "B's behaviour", even if the need for it/them hasn't been dreamed-up yet.

Yeah, basically that's the only pattern to follow (AFAIK)... so (rightly or wrongly) you may as well make the best of it ;-)

Cheers. Keith.

拿命拼未来 2024-11-09 22:48:53

尽管我依赖包访问,但这当然是一种方法;不提供构造函数注入点,而只是将测试放在与正在测试的 bean 相同的包中。这样,您的测试就可以直接访问该值(假设它不是私有的):

@Test
public void EJBInjectionTest() {
   A a=new A();
   a.b=new B() {
       // mock functionality here, of course...
   };
   assertNotNull(a.b);
}

It's certainly one way to do it, although I'd rely on package access; don't provide a constructor injection point, but simply have your test in the same package as the bean being tested. That way, your test can just access the value directly (assuming it's not private):

@Test
public void EJBInjectionTest() {
   A a=new A();
   a.b=new B() {
       // mock functionality here, of course...
   };
   assertNotNull(a.b);
}
纸伞微斜 2024-11-09 22:48:53

根据 这篇文章(Mockito 和依赖注入),Mockito 支持注入模拟资源。

public class ATest
{
    @InjectMocks
    private A a; //this is your class under test into which the mocks will be injected.

    @Mock
    private B b; //this is the EJB to be injected.

    @Before
    public void setUp()
    {
        MockitoAnnotations.initMocks(this);
    }

}

您还可以注入多个模拟。只需按照与 B b 相同的方式声明它们即可。
initMocks 部分也可以根据您的需要在每个测试或 BeforeClass 设置方法中完成。

According to this article (Mockito and Dependency Injection), Mockito has support for injecting mocked resources.

public class ATest
{
    @InjectMocks
    private A a; //this is your class under test into which the mocks will be injected.

    @Mock
    private B b; //this is the EJB to be injected.

    @Before
    public void setUp()
    {
        MockitoAnnotations.initMocks(this);
    }

}

You can also inject multiple mocks. Just declare them in the same way as we did for B b.
The initMocks part can also be done in each test or in a BeforeClass setup method depending on your needs.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文