java inject作用,Java:将带有Inject注释的类添加为Junit

本文讨论了如何在JUnit测试中处理依赖注入,特别是当依赖在构造函数中使用时。通过引入Guice的Assisted Injection,可以解决在测试时因依赖未初始化导致的空指针异常。解决方案包括在实现类中使用@Assisted注解来指导构造函数注入,并在测试类中使用Mockito创建mock对象以模拟依赖。
摘要由CSDN通过智能技术生成

@Singleton

public class RealWorkWindow implements WorkWindow {

@Inject private Factory myFactory;

public RealWorkWindow (

LongSupplier longSupplier

) {

defaultWindow = myFactory.create(() -> 1000L);

workWindow = myFactory.create(longSupplier);

}

...

As you can see I am Injecting a factory class (injected via FactoryModuleBuilder)

Test code

@Test

public class RealWorkWindowTest {

private RealWorkWindow testWindow;

@BeforeMethod

void setup() {

MockitoAnnotations.initMocks(this);

testWindow = spy(new RealWorkWindow(() -> 1L));

}

Factory.py

public interface RealWorkWindowFactory {

RealWorkWindowFactory create(LongSupplier longSupplier);

}

Module

install(new FactoryModuleBuilder()

.implement(WorkWindow.class, RealWorkWindow.class)

.build(RealWorkWindowFactory.class));

When I run the test RealWorkWindowTest the test fails with NPE that factory does not exists, which makes sense since I dont think injection runs.

How can I test with Injection in junit? or mock properly?

But the problem that I have is that mock is used IN constructor so it's still a null when instantiate the test object (because i have not called Mockito.init yet)

解决方案

Use constructor injection when using @Assisted injection

AssistedInject generates an implementation of the factory class automatically. To use it, annotate the implementation class' constructor and the fields that aren't known by the injector:

And later:

AssistedInject maps the create() method's parameters to the corresponding @Assisted parameters in the implementation class' constructor. For the other constructor arguments, it asks the regular Injector to provide values.

As they are only available at that time, Guice will only inject fields after the constructor call. This translates for you in the fact that you must use the constructor injection, and no other mechanism (unless you have an extension that allows @PostConstruct or similar).

So let's rewrite your code according to that. Write your RealWorkWindow as follow:

@Singleton

public class RealWorkWindow implements WorkWindow {

private final WorkWindow defaultWindow;

private final WorkWindow workWindow;

@Inject

public RealWorkWindow(Factory myFactory, @Assisted LongSupplier longSupplier) {

defaultWindow = myFactory.create(() -> 1000L);

workWindow = myFactory.create(longSupplier);

}

}

Your code can then become testable as follows:

@RunWith(MockitoJunitRunner.class)

public class RealWorkWindowTest {

@Mock

Factory myFactory;

@Mock

WorkWindow defaultWindow;

@Mock

WorkWindow workWindow;

RealWorkWindow realWorkWindow;

@BeforeEach

void setup() {

when(myFactory.create(any(LongSupplier.class)))

.thenReturn(defaultWindow) // First call

.thenReturn(workWindow); // Second call

realWorkWindow = new RealWorkWindow(myFactory, () -> 1000L);

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值