I have an application with lots of MEF, it's Import all the way down. In the debugger, with Break on Exception set, if a part is not found I can see an ImportCardinalityMismatchException being raised that tells me exactly what the missing import is. But then it gets swallowed, I assume by MEF, and eventually a log message pops out telling me about a different component that depends (possibly indirectly) on the failed one. Is it possible to get hold of that original failure outside of the debugger?
Yes, in .NET 4.5 you can use one of the CompositionContainer constructor overloads which accepts a CompositionOptions enum. You need to pass it the DisableSilentRejection enum value.
One solution in .Net 4 is to use the [Import(AllowDefault = true)] attribute on the parameters to the importing constructor, then handle/log the failure yourself in the constructor body:
[ImportingConstructor]
public SomeView([Import(AllowDefault = true)] SomeViewModel context)
{
if (context == null)
{
LogManager.GetLogger("Composition").Error("No object found to satisfy import of 'SomeViewModel'");
throw new ArgumetnNullException ("SomeViewModel");
}
Related
Another question appeared during my migration from an E3 application to a pure E4.
I got a Structure using inheritance as in the following pic.
There I have an invocation sequence going from the AbstractRootEditor to the FormRootEditor to the SashCompositeSubView to the TableSubView.
There I want to use my EMenuService, but it is null due to it can´t be injected.
The AbstractRootEditor is the only class connected to the Application Model (as a MPart created out of an MPartDescriptor).
I´d like to inject the EMenuService anyway in the AbstractSubView, otherwise I would´ve the need to carry the Service through all of my classes. But I don´t have an IEclipseContext there, due to my AbstractSubView is not connected with Application Model (Do I ?).
I there any chance to get the service injected in the AvstractSubView?
EDIT:
I noticed that injecting this in my AbstractSubView isn´t possible (?), so I´m trying to get it into my TableSubView.
After gregs comment i want to show some code:
in the AbstractRootEditor:
#PostConstruct
public final void createPartControl(Composite parent, #Active MPart mPart) {
...
ContextInjectionFactory.make(TableSubView.class, mPart.getContext());
First I got an Exception, saying that my TableSubView.class got an invalid constructor, so now the Constructor there is:
public TableSubView() {
this.tableInputController=null;
}
as well as my Field-Injection:
#Inject EMenuService eMenuService
This is kind of not working, eMenuService is still null
If you create your objects using ContextInjectionFactory they will be injected. Use:
MyClass myClass = ContextInjectionFactory.make(MyClass.class, context);
where context is an IEclipseContext (so you have to do this for every class starting from one that is injected by Eclipse).
There is also a seconds version of ContextInjectionFactory.make which lets you provide two contexts the second one being a temporary context which can contain additional values.
Am having a little trouble understanding what and what cannot be done using FakeItEasy. Suppose I have a class
public class ToBeTested{
public bool MethodToBeTested(){
SomeDependentClass dependentClass = new SomeDependentClass();
var result = dependentClass.DoSomething();
if(result) return "Something was true";
return "Something was false";
}
}
And I do something like below to fake the dependent class
var fakedDepClass = A.Fake<DependentClass>();
A.CallTo(fakedDepClass).WithReturnType<bool>().Returns(true);
How can i use this fakedDepClass when am testing MethodToBeTested. If DependentClass was passed as argument, then I can pass my fakedDepClass, but in my case it is not (also this is legacy code that I dont control).
Any ideas?
Thanks
K
Calling new SomeDependentClass() inside MethodToBeTested means that you get a concrete actual SomeDependentClass instance. It's not a fake, and cannot be a FakeItEasy fake.
You have to be able to inject the fake class into the code to be tested, either (as you say) via an argument to MethodToBeTested or perhaps through one of ToBeTested's constructors or properties.
If you can't do that, FakeItEasy will not be able to help you.
If you do not have the ability to change ToBeTested (and I'd ask why you're writing tests for it, but that's an aside), you may need to go with another isolation framework. I have used TypeMock Isolator for just the sort of situation you describe, and it did a good job.
I have many classes (45 at least). Each one has its own method to validate something that is repeated in all the classes, so I have the code repeated in all those classes. I'd like to have one method and call it from all the classes.
If have the following code to know if a mobile device is connecting to the server
private boolean isMobileDevice(HttpServletRequest request) {
String userAgent = request.getHeader("user-agent");
return userAgent.indexOf("Windows CE") != -1;
}
As said before, This method is repeated in many classes
Is it possible in Intellij Idea and/or Eclipse to do that refactor? and How can I perform that refactor?
private boolean isMobileDevice(HttpServletRequest request) {
String userAgent = request.getHeader("user-agent");
return userAgent.indexOf("Windows CE") != -1;
}
I bet that my Eclipse will warn me that this method can be declared as static, because it does not use any fields of enclosing class - such method should be declared as static to let you know that it is not essentially needed in enclosing class, and if there will be a reason (having 45 methods in place of one is THE REASON) you can move it to some other class, and just call it as public or package method.
EDIT: It did: The method isMobileDevice(HttpServletRequest) from the type Test can be declared as static:
So:
Copy it to some other class, make it public static boolean isMobileDevice(HttpServletRequest request) and use in every classes where it was private boolean.
That's all, but I don't see and way to make it with automatic refactor.
With Intellij you could try "Refactor" > "Find and Replace Code Duplicates...".
It will replace the duplicate code by a static function.
I have an #Embeddable class that uses property access to wrap another object that's not directly mappable by JPA via field access. It looks like this:
#Embeddable
#Access(AccessType.PROPERTY)
public class MyWrapper {
#NotNull
#Transient
private WrappedType wrappedField;
protected MyWrapper() {
}
public MyWrapper(WrappedType wrappedField) {
this.wrappedField = wrappedField;
}
#Transient
public WrappedType getWrappedField() {
return wrappedField;
}
public void setWrappedField(WrappedType wrappedField) {
this.wrappedField = wrappedField;
}
#Column(name = "wrappedTypeColumn")
protected String getJPARepresentation() {
return wrappedField.toString();
}
protected void setJPARepresentation(String jpaRepresentation) {
wrappedField = new WrappedType(jpaRepresentation);
}
}
Persisting an #Entity with a MyWrapper field works fine. But when I execute a query to load the Entity from the database, I get a NullPointerException. The stacktrace and some debugging shows that Eclipselink creates a new instance of MyWrapper by calling its default constructor and then calls the setJPARepresentation() method (as expected).
But now the unexpected happens: the stacktrace shows that the getJPARepresentation() is called from inside the setter, which then of course leads to a NullPointerException when return wrappedField.toString() is executed.
java.lang.NullPointerException
at MyWrapper.getJPARepresentation(MyWrapper.java:27)
at MyWrapper.setJPARepresentation(MyWrapper.java)
... 109 more
Fact is, there is obviously no call to the getter in the code and the stacktrace shows no line number indicating from where in the setter called the getter. So my conclusion would be, that the bytecode weaver of Eclipselink generated the call to the getter.
It's easy to build a workaround, but my question is: Why does Eclipselink do that?
P.S: I'm using EclipseLink 2.3.2.v20111125-r10461 in a GlassFish Server Open Source Edition 3.1.2 (build 23)
When weaving is enabled (default on Glassfish), EclipseLink will weave code into property get/set methods for,
change tracking
fetch groups (partial objects)
lazy (relationships)
For change tracking support the set method will be weaved to check if the new value is different than the old value, so it must call the get method to get the old value.
Now this is still odd, as since your are building a new object, I would not expect the change listener to be set yet, so would expect the change tracking check to be bypassed. You could decompile the code to see exactly what was generated.
The easiest fix is to just put in a null check in your get method, which is probably best in general for your code. You could also switch to field access, which will not have issues with side-affects in get/set methods. You could also use a Converter to handle the conversion, instead of doing the conversion in get/set methods.
When executing the second line of this code Rhino Mocks throws an InvalidOperationException with a message "This action is invalid when the mock object is in replay state"
var mockScanner = MockRepository.GenerateMock<PortScanner>(null);
mockScanner.Expect((scanner => { scanner.Scan(null, null); }));
Stepping through the code in a debugger one can see the debugger run the method defined in the class and directly after control leaves this method the exception occurs.
This similar code in another test does work without issue
var mockView = MockRepository.GenerateMock<IScanView>(null);
mockView.Expect(view => { view.Close(); });
var controller = new ScanController(mockView);
controller.Exit();
mockView.VerifyAllExpectations();
The only difference that I can think of that might be of any consequense between theese two tests is that Exit is a member on an interface while Scan is a virtual member on a class
What am I missing?
Update
Further exploration has indicated that this is related to the way Rhino handles virtual methods. I am focusing mmy study of the documentation here now
The exception was caused because Rhino Mocks did not have the required level of access to the type in order to mock it properly. Granting internal access to the Rhino Mocks assembly using InternalsVisibleTo solved the problem.
It's noteworthy that this does not affect interfaces. I believe the reason for this is because the mocking framework needs to override the implementation on a class where there is none on an interface.
What happens if you remove the extra set of parentheses from the first expression?
var mockScanner = MockRepository.GenerateMock<PortScanner>(null);
mockScanner.Expect( scanner => { scanner.Scan(null, null); } );