Consider the existence of a Foo some time in the app. Now Bar objects depend on a Foo. I want to create this bar based on this foo I already have, but Guice creates a new instance of Foo every time. I can have a lot of Foos, so I cannot #Singleton Foo.
I tried to use scopes for this purpose, but I don't know what I am doing wrong.
I know this can be solved with #AssistedInject but I do not want to take this solution because these associations are common in my context and the dependency is only one. Also, since I am working on creating a tool based on Guice, all I got is a Foo, and Bar.class and I want to create instances of Bar with the given Foo. I am not aware if there are any factories or so.
public class InjectionTest2 {
public static void main(String[] args) {
Module module = new AbstractModule() {
ReceiverScope receiverScope = new ReceiverScope();
#Override
protected void configure() {
bindScope(ReceiverScoped.class, receiverScope);
bind(Foo.class);
}
#Provides
#Singleton
public ReceiverScope scope() {
return receiverScope;
}
};
Injector injector = Guice.createInjector(module);
Foo foo = injector.getInstance(Foo.class); //assume a given foo
ReceiverScope scope = injector.getInstance(ReceiverScope.class);
scope.enter();
scope.seed(Key.get(Foo.class, Existing.class), foo);
Bar bar = injector.getInstance(Bar.class);//Create a Bar with this foo
scope.exit();
}
private static class Foo {
#Inject
public Foo() {
System.out.println("foo created" + toString());
}
}
#ReceiverScoped
private static class Bar {
#Inject
public Bar(#Existing Foo foo) {
System.out.println("bar created with foo" + foo.toString());
}
}
#Retention(RetentionPolicy.RUNTIME)
#BindingAnnotation
private static #interface Existing {
}
}
ReceiverScope is a class identical to Simple Scope given here.
Another way I can think of is if I manually iterate Bar's contructor parameters and for each parameter, I ask guice to give me an instance, but if it is a Foo, I give my value. But won't this give me a very hard time? I mean I will have to consider a lot of things, because in the constructor might be extra Qualifiers on parameters and stuff...
EDIT (after #kendavidson's answer):
This is true. I thought it makes my question more complicated, that's why I did not include it. Bar is an interface. Fields in Foo contain an annotation which has a Class<? extends Bar> barClass() method. For example:
#ContainsBars
private static class Foo {
#MakeBar(BlueBar.class)
private Something aSomething;
#MakeBar(BlackBar.class)
private SomethingElse aSomethingElse;
#Inject
public Foo() {
//create aSomething
//create aSomethingElse
}
}
Now, whenever Guice injects a #ContainsBars, I listen it via a TypeListener and I go to create the bars. I scan Foo.class and I get BlueBar.class & BlackBar.class.
The problem I am trying to solve is, how to create BlueBar when BlueBar has a dependency to Foo.class? Whenever this happens, I need to create the BlueBar with the Foo I was taken from the listener.
Reflecting constructor was one of my thoughts however it sounds a pain in the ... I guess, it will need to iterate each parameter of the #Inject constructor of BlueBar.class. If the parameter is of type Foo, I give my Foo. If it is a different type, ask the injector to give me an instance of that type. The thing is, how do I do this. When Guice injects, it takes in consideration possible binding annotations (Qualifiers) and generics. Doing that again, sounds pain.
In the other hand, these #ContainsBars annotated classes by 99% chance have no relation to each other.
Adding a method to Bar interface like setFoo(Foo f) will not work. It will have to be a generic. Therefore, method injection with a setter will be cast unsafe. As far as I am aware of, and assuming BlackBar implements Bar<Foo>, when I will Bar b = injector.getInstance(BlackBar.class), It will give me a Bar<?>. That means, I can't call the setter safely.
Field injection is interesting. Having something like this:
public class BlackBar implements Bar {
private MyDepedency dep;
#Existing
private Foo foo;
public BlackBar(Foo foo,MyDepedency dep) {
this.foo = foo;
this.dep = dep;
}
}
seems ok. Whenever, I get a BlackBar, I go find the #Existing field, and then set the value. I do not care for the value in constructor. Let's say:
Foo foo = ...
Bar bar = injector.getInstance(BlackBar.class);
setExistingFieldWithValueOf(foo,bar);
The problem here is that whenever I ask injector, it sees the Foo dependency, and it is creating a new Foo in order to inject. Then, I go change its value. This will cause an infinite loop since during Foo injection which is a #ContainsBar, the process will be repeated. Even if i manage to stop the infinite loop, still the creation of a new Foo that will never be used seems a bad overhead. If there is a way to inject with null value to foo in the constructor, let me know. I will use this.
This might be a shot in the dark and if I'm missing something please let me know. First off, I definitely think AssistedInject is a solid choice, with a minimal footprint for each Bar.
A couple things missing from your question and comments are:
What are some sample annotated fields of Foo?
How do you expect multiple Bars to be created?
Are you dealing with Bar and OtherBar implementations? Or are you dealing with Bar and <T extends Bar> interface?
Based on some of these things, it might be doable with:
// BarProvider.java
public class BarProvider {
// Get the injector, frowned upon but required
#Inject Injector injector;
public <T extends Bar> T get(Foo foo, String fieldname) {
// Provider right now returns on Bar at a time, I'm guessing this is based on
// fieldname, which can lookup the #Annotation to get the class
Annotation annotation = ...;
Bar bar = ...;
// Now you need to create the bar, this can be done in a couple of ways:
// Option 1 is to reflect the Bar(Foo) constructor
// then doing an injector.injectMembers(bar) to fill the remaining fields
// Option 2 is to use field/method injection and doing a combination of
// Bar bar = injector.getInstance(annotatedClass); followed by
// bar.setFoo(foo);
return bar;
}
}
// Foo.java
public class Foo {
}
// Bar.java
public interface Bar {
}
// ABar.java
public class ABar {
}
// BBar.java
public class BBar {
}
In both cases you would not #Inject the Foo field in Bar. Again this makes some assumptions on how you know which field you want to look at in Foo for the annotation class type.
Another option would be to return all of them using:
public <T extends Bar> T[] get(Foo foo) {
// Same thing but loop through all Annotated fields
}
In both cases I'm assuming that Bar and OtherBar are actually implementations of the same interface which means you'd always be using Bar as a return type. It's still possible otherwise, just a little more annoying.
Hopefully I'm not way off base, and something might be helpful. But again AssistedInject the way it was described above would still probably be a better solution.
Edit 1 - Circular Dependencies
If you have these classes, for example, you will not have issues with Foo being injected and then overwritten.
public abstract class Bar<T> {
T foo;
setFoo(T foo) {
this.foo = foo;
}
}
public class BlackBar extends Bar<Foo> {
#Inject Dep1 dep1; // Injected
#Inject Dep2 dep2; // Injected
BlackBar() {}
}
#ContainsBar
public class Foo {
#BlackBar
SomeObject someObject;
}
Now in your example:
Foo foo = injector.getInstance(Foo.class); // Inject SomeObject
Bar bar = injector.getInstance(BlackBar.class); // Inject Dep1 and Dep2
bar.setFoo(foo); // Set Foo manually
This won't cause the problem you think it does, because Foo foo is NOT annotated with #Inject therefore Guice won't create a new one when building BlackBar.
But this still doesn't answer how exactly you're USING your bars. I also have a feeling I'm missing something very important to the end goal.
Related
I see a couple different ways of mocking objects. What exactly are the differences between this approache using InjectMocks and the approach shown here: https://github.com/mockito/mockito/wiki/Mocking-Object-Creation?
#ExtendWith(MockitoExtension.class)
public class MyTest() {
#Mock ClassB uut;
#InjectMocks ClassA cA;
#Test
public TestOne() {
...
}
}
where
public class ClassA() {
public ClassA() {
ClassB temp = new ClassB();
}
}
versus the method shown here:
https://github.com/mockito/mockito/wiki/Mocking-Object-Creation
What exactly is the difference?
I believe there is no essential difference between those approaches.
InjectMocks approach
Actually for it to work, your class should accept the dependencies through the constructor or setters (and it never works with both). I would say that this approach makes the testing easier because you inject whatever you want to your class object at the initialization phase.
class Foo {
private final Bar bar;
public Foo(final Bar bar) {
this.bar = bar;
}
}
If this is our class under test, then all #InjectMock does is to create mocks, and do the following:
Foo foo = new Foo(barMock);
Apart from being testable, imagine if the Bar is an interface, then you can possibly you can switch between multiple implementations of it without actually touching the class code (ideally). If you have a DI framework, that's even easier. So, basically this format of the class makes it flexible.
Using one-line methods for object creation
Let's say this is our class under test. As you can see, I am initializing the property inside the constructor. Legally, with no reflection magic, I cannot put a mock bar variable neither during initialization nor after that.
class Foo {
private final Bar bar;
public Foo() {
this.bar = new Bar();
}
}
The reason that Mockito docs tell you to switch to either a one-liner method or a Factory helper is that:
Mockito cannot mock constructors, which means you cannot put a mock object in the place of bar without reflection, and you can only do that after the initialization. Generally, to point of my view on testing, reflection should be avoided as much as possible.
One-liner functions are looking as clean as constructors and they can be descriptive (like static factory methods).
So, when you switch your class to look like this:
class Foo {
private final Bar bar;
public Foo() {
this.bar = makeBar();
}
Bar makeBar() {
return new Bar();
}
}
Now, you can put a spy, and just mock the makeBar method easily. The same applies to the factory method as well. To be honest, the factory approach looks a bit wordy to me, but still, I am sure there will be times when it may come handy.
So here's the thing. I'm trying to inject some fields with guice, but it turns out that they are always null (not trying to use them on the constructor).
public class A {
#Inject
private SomeClass bar;
public A() {
foo();
}
public someMethod() {
bar.doSth();
}
}
public class B {
private A a;
public B() {
a = new A();
}
public someOtherMethod() {
a.someMethod();
}
}
Now whenever the app executed someOtherMethod and a tries to run bar.doSth a nice NullPointerException is raised.
So in order to fix this i ended Injecting the field manually inside the constructor:
public A() {
final Injector injector = Guice.createInjector();
bar = injector.getInstance(SomeClass.class);
}
But this is ugly, unclear, has a lot of boilerplate and I'm forced to do it on many places which make it tedious.
Is there any other way to archive this? Or an explanation of why the field is not being injected?
Thanks
Note:
I'm currently unavailable to do the propper injection on the constructor (with bar as a parameter) because of the refactoring it would imply. The project is now under heavy production and thus this kind of refactoring can't be done right now.
The IOC container only controls what you tell it to control. It doesn't know about the A inside of B, because it's being constructed directly, not managed by the container. You need to inject the A as well:
public class B {
#inject private A a;
public B() {}
...
}
And you can't just call new B() either, you need to inject the B as well.
I'm working on a team project which has a very coupled code. I'm trying to increase the unit test coverage and I've faced the following scenario:
class Foo {
static void methodA () {
Bar b = new Bar();
b.getContent();
}
}
class Bar {
#Inject
DBAcessor mDBAcessor;
Bar () {
Dagger2.getInjector().inject(this);
}
public Object getContent() {
mDBAcessor.fetchData();
}
}
I want to unit test methodA(), however I don't know if it is possible to do it without passing the DBAcessor object via constructor to Bar() class. Bar should be a POJO model being widely used throughout the project, hence, I don't know if it would be a good idea to change its constructor and impact so many other classes. Any tips on how should I approach this scenario?
That is wrong design.
Whenever you have an access to the constructor, pass class dependencies into constructor. That really eases unit testing. Class Bar should look:
class Bar() {
#Inject DBAcessor mDBAcessor;
Bar (DBAcessor dbAcessor) {
this.mDBAcessor = dbAcessor;
}
public Object getContent() {
mDBAcessor.fetchData();
}
}
Dagger2 methods declared in Component should only be used inside object you don't have an access to the constructor (Activity or Fragment).
Then nothing prevents you from doing that:
DBAccessor dbAccessor = Mockito.mock(DBAccessor.class);
Bar bar = new Bar(dbAccessor);
bar.getContent();
verify(bar, times(1)).fetchData();
If you really need to stick to such design, then you can't make unit tests on such object, as Dagger2 depends on Application object, which needs Context, which you cannot emulate in unit tests. Write your test as androidTest, create appropriate Activity, fetch Bar object from it and test it.
I want to write a function that, given an arbitrary java bean as an argument, returns an object that is a copy of that bean but that belongs to an anonymous subclass of the bean's type that contains an additional property. Let me illustrate with an example of what I have so far:
Foo.java:
import lombok.Data;
import lombol.AllArgsConstructor;
#Data
#AllArgsConstructor
public class Foo {
private String bar;
private String baz;
}
Garply.java:
public class Garply {
Foo fooWithQux(Foo foo, String quxVal) {
return new Foo(foo.bar, foo.baz) {
private String qux;
public String getQux() {
return quxVal;
}
};
}
}
This seems silly because I can never actually call getQux(), but a tool I work with uses reflection to successfully find the qux property and do what I want with it.
My issue is that I don't want to have separate fooWithQux() functions for each type that I want to be able to add the qux property to. Ideally I'd have something like beanWithQux() that accepts objects of arbitrary type. I think I could make this work with something like the following:
public T beanWithQux<T>(T bean, String quxVal) {
class BeanWithQux extends T {
private String qux;
BeanWithQux(T bean, String quxVal) {
// Here's where I'd like to copy all of the properties
// from the Bean into the BeanWithQux
qux = quxVal;
}
public getQux() {
return qux;
}
}
return BeanWithQux(bean, quxVal);
}
Here's where I'm stuck. I don't know to copy all of the properties from the given object into my new object. Anyone have ideas? Ideally there would be something I could do using lombok (I control the Foo class and can add annotations like #Builder if need be) as opposed to writing a bunch of reflection magic myself.
Thanks!
I think in this case using runtime bytecode weaving is a better approach, since you don't need to call the methods in your own codebase.
I have an object Foo that holds a reference to object Bar that has a reference to object Baz, and in order for Foo to be valid, Bar has to have a valid, non-null reference to Baz.
The problem is that Bar doesn't require a valid, non-null Baz to be valid, so I can't simply put the validation in there, I need it to be within Foo.
Here's a simple pseudo-version of the class structure I'm talking about:
class Foo {
// Bar needs to have a valid Baz. Something like this would be ideal:
// #HasAValidBaz(message="Baz is required")
Bar bar;
}
class Bar {
// Baz can be null and Bar will still be valid
// But if there _is_ a Baz, it needs to be valid
Baz baz;
}
class Baz {
#NotBlank(message="My String is required")
String myString;
}
I know I can do this with class-level custom validation annotations, but the problem is that those error objects and corresponding messages apply to the class instance and not the field instance, which I need to be able to easily display the error message next to the correct form field.
Is there a good way to do this, or am I stuck with implementing this validation in the controller?
Annotations are nice, but maybe not appropriate in this case. The problem is that annotations are marked on the actual class, meaning you can't really have two types of validation annotations on the same class - which seems to be your issue. It would maybe be more appropriate for you to use the old-school Spring MVC approach of implementing the Spring Validator class. Here's an example:
public class FooValidator implements Validator {
#Override
public boolean supports(Class<?> clazz) {
return Foo.class.equals(clazz);
}
#Override
public void validate(Object target, Errors errors) {
Foo foo = (Foo) target;
if(foo.getBar() == null) {
errors.rejectValue("bar", "bar[emptyMessage]");
}
else if(foo.getBar().getBaz() == null){
errors.rejectValue("bar.baz", "bar.baz[emptyMessage]");
}
}
}
And your Spring controller is still pretty much the same as it is using annotations:
#Controller
public class FooController {
#InitBinder("foo")
protected void initBinder(WebDataBinder binder) {
binder.setValidator(new FooValidator());
}
#RequestMapping(value="fooPage", method = RequestMethod.POST)
public String processSubmit(#Valid Foo foo, BindingResult result, ModelMap m) {
if(result.hasErrors()) {
return "fooPage";
}
...
return "successPage";
}
}