Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dagger2: How to use @Inject in a JUnit test?

I would like to have the ability to inject dependencies into JUnit tests with Dagger 2 (I'm new to this framework). Coming from Spring, there you can do something like this:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = MyApplication.class)
public class MyTestClass {

    @Autowired
    private MyService service;

    @Test
    public void testMySerivce() { /* ... */ }

}

... but with Dagger 2 I have not yet found a solution that does not rely on an explicit DaggerMyComponent.builder().build().myService().

Ideally, I would imagine the solution to look something like the following:

// tell JUnit that dagger needs to do some post processing
@RunWith(DaggerJUnit4Runner.class)
// tell dagger which component classes to use for injection
@Components(MyComponent.class)
public class MyTestClass {

    @Inject
    private MyService service;

    @Test
    public void testMySerivce() { /* ... */ }

}

Unfortunately, there is no DaggerJunit4Runner.

Any hints on how this could be accomplished would be greatly appreciated.

like image 672
Alan47 Avatar asked Oct 03 '18 21:10

Alan47


People also ask

What is inject in dagger?

Dagger 2 is a compile-time android dependency injection framework that uses Java Specification Request 330 and Annotations. Some of the basic annotations that are used in dagger 2 are: @Module This annotation is used over the class which is used to construct objects and provide the dependencies.

What does @singleton annotation do?

The @Singleton annotation is used to declare to Dagger that the provided object is to be only initialized only once during the entire lifecycle of the Component which uses that Module.

What is dagger2 used for?

Dagger is arguably the most used Dependency Injection, or DI, framework for Android. Many Android projects use Dagger to simplify building and providing dependencies across the app. It gives you the ability to create specific scopes, modules, and components, where each forms a piece of a puzzle: The dependency graph.


Video Answer


1 Answers

I haven't seen any built-in feature for this, or any prominent testing library that supports this.

Dagger does all its dependency wiring at compile time, and only in ways you tell it to; unlike Spring, there's no code written to read a testing class at runtime or supply the dependencies it needs. Dagger's appeal over Guice and Spring comes from compile-time compilation, validation, and optimization. Though what you describe would be very useful, that kind of reflection is antithetical to Dagger's original motivations. Either your Dagger component is compiled with the generated code to inject the test, or you need to be able to pull those dependencies out independently as you've listed above.

For unit tests you'll probably need to skip Dagger and create your classes or their mocks manually; for system or integration tests, you'll need to expose all of the classes you need on the component definition. If you want to replace dependencies with test doubles for repeatability or isolation, you'll need to make your component sufficiently configurable to accept the replacement implementations, or you'll need to create a new for-testing Component implementation that uses the test doubles instead of the real implementations.

like image 189
Jeff Bowman Avatar answered Oct 12 '22 07:10

Jeff Bowman