public class TestBase {
protected Injector injector = Guice.createInjector(new AbstractModule() {
@Override
protected void configure() {
bind(HelloService.class);
}
});
@Before
public void setup () {
injector.injectMembers(this);
}
}
然后您的测试可以像这样获得注入的 HelloService
public class HelloServiceTest extends TestBase {
@Inject
HelloService service;
@Test
public void testService() throws Exception {
//Do testing here
}
}
In case anyone stumbles upon this question and wants to see how to get Guice annotations working from unit tests, extend your tests from a base class like the one below and call injector.injectMembers(this);
public class TestBase {
protected Injector injector = Guice.createInjector(new AbstractModule() {
@Override
protected void configure() {
bind(HelloService.class);
}
});
@Before
public void setup () {
injector.injectMembers(this);
}
}
Then your test can get an injected HelloService like this
public class HelloServiceTest extends TestBase {
@Inject
HelloService service;
@Test
public void testService() throws Exception {
//Do testing here
}
}
您确实应该避免在单元测试中使用 Guice,因为每个测试都应该足够小,以便手动 DI 易于管理。通过在单元测试中使用 Guice(或任何 DI),您可以隐藏一个警告,即您的类变得太大并且承担了太多的责任。
为了测试引导程序代码和集成测试,可以为每个测试创建一个不同的注入器。
You should really avoid using Guice in unit tests as each test should be small enough that manual DI is manageable. By using Guice (or any DI) in unit tests you are hiding away a warning that your class is getting too big and taking on too many responsibilities.
For testing the bootstrapper code and integration tests then yes create a different injector for each test.
JUnit5 is still new to me, so I may be looking into templates, but so far the Extensions seem to do the trick.
With JUnit4 we use a similar approach, except that the injection takes place within the createTest method of our custom test runner, and then each test implements a RequiresInjection interface that has a "getModule" method.
I should probably give a shout out to TestNG as well, as Guice support is built right in. Usage is as simple as this:
@Guice({SomeObjectModule.class})
public class MyTest {
@Inject
SomeObject someObject;
}
I won't recommend using it now (documentation is really terrible), but looking at their approach can make you think clear about how DI should be done in jUnit.
I found AtUnit to be an excellent complement to Guice (it even deals with mock framework integration).
This makes the Unit Test classes extremely clear and concise (never see an Injector there) and, where appropriate, also lets you exercise your production bindings as part of your unit tests.
发布评论
评论(7)
如果有人偶然发现这个问题并希望了解如何从单元测试中获取 Guice 注释,请从如下基类扩展您的测试并调用
injector.injectMembers(this);
然后您的测试可以像这样获得注入的
HelloService
In case anyone stumbles upon this question and wants to see how to get Guice annotations working from unit tests, extend your tests from a base class like the one below and call
injector.injectMembers(this);
Then your test can get an injected
HelloService
like this您确实应该避免在单元测试中使用 Guice,因为每个测试都应该足够小,以便手动 DI 易于管理。通过在单元测试中使用 Guice(或任何 DI),您可以隐藏一个警告,即您的类变得太大并且承担了太多的责任。
为了测试引导程序代码和集成测试,可以为每个测试创建一个不同的注入器。
You should really avoid using Guice in unit tests as each test should be small enough that manual DI is manageable. By using Guice (or any DI) in unit tests you are hiding away a warning that your class is getting too big and taking on too many responsibilities.
For testing the bootstrapper code and integration tests then yes create a different injector for each test.
我认为使用 DI 会让单元测试代码更加简单,我总是使用 DI 进行单元测试以及集成测试。
如果没有 DI,一切都很难编码。使用 Guice Inject 或 Spring Autowired 。就像我的测试代码如下:
I think using
DI
will make unit test code more simple, I always Use DI for unit test and also for integration test.Without DI everything feels hard to code. Either using
Guice Inject or Spring Autowired
. like my test code bellow:这取决于所使用的 JUnit 版本。我们的团队已成功使用 Junit4,现在正在研究 JUnit5。
在 Junit5 中我们使用扩展。
然后每个测试都使用 RequiresInjection 注释,它可以接受内部模块数组进行聚合,或者不接受内部模块数组以使用默认值。
这是注释:
JUnit5 对我来说仍然是新的,所以我可能正在研究模板,但到目前为止,扩展似乎可以解决问题。
对于 JUnit4,我们使用类似的方法,只不过注入发生在自定义测试运行器的 createTest 方法中,然后每个测试都实现一个具有“getModule”方法的 RequiresInjection 接口。
我可能也应该对 TestNG 表示感谢,因为 Guice 支持是内置的。用法就像这样简单:
This depends on which version of JUnit is being used. Our teams have used Junit4 successfully and are now looking into JUnit5.
In Junit5 we use extensions.
Then each test uses the RequiresInjection annotation, which can accept an array of inner modules to aggregate, or none to use the default.
And here's the annotation:
JUnit5 is still new to me, so I may be looking into templates, but so far the Extensions seem to do the trick.
With JUnit4 we use a similar approach, except that the injection takes place within the createTest method of our custom test runner, and then each test implements a RequiresInjection interface that has a "getModule" method.
I should probably give a shout out to TestNG as well, as Guice support is built right in. Usage is as simple as this:
看看 Guice Berry。
我现在不建议使用它(文档真的很糟糕),但是看看他们的方法可以让你清楚地思考在 jUnit 中应该如何完成 DI。
Take a look at Guice Berry.
I won't recommend using it now (documentation is really terrible), but looking at their approach can make you think clear about how DI should be done in jUnit.
我发现 AtUnit 是 Guice 的绝佳补充(它甚至可以处理模拟框架集成)。
这使得单元测试类极其清晰和简洁(永远不会在那里看到注入器),并且在适当的情况下,还允许您将生产绑定作为单元测试的一部分进行练习。
I found AtUnit to be an excellent complement to Guice (it even deals with mock framework integration).
This makes the Unit Test classes extremely clear and concise (never see an
Injector
there) and, where appropriate, also lets you exercise your production bindings as part of your unit tests.我建议使用我最近编写的这个框架 Guice-Behave。
它非常简单,通过两个注释,您可以在应用程序的同一上下文中运行测试。
您可以在 Guice 模块中定义您的模拟,这样就可以很容易地重用它们。
I suggest this framework I have recently written Guice-Behave.
It is very simple, with two annotations you can run the test in the same context of your application.
You can define your mocks inside the Guice module and in this way it is very easy to re-use them.