Mocked repository does not trigger as expected - spring

I have a Controller Unit test using Mockito and MockMvc.
After a POST request, the POSTed object is resolved correctly, but my repository mock is not triggered.
Here is the mock code:
Date mydate = new Date();
Notification not = new Notification();
not.setId(-1L);
not.setUserid("BaBlubb");
not.setTimestamp(mydate);
not.setContent("MyContent");
Notification not2 = new Notification();
not2.setId(1L);
not2.setUserid("BaBlubb");
not2.setTimestamp(mydate);
not2.setContent("MyContent");
when(notificationRepository.save(not)).thenReturn(not2);
So this really just should simulate the saving of an object (ID is set and a route is generated out of it).
Unfortunately, the repository always returns null, so my code later fails when trying to return a new created Route out of null.
The mocks are correctly injected and do work for e.g. String comparison or if I only check for the function to have been called, I just can't get it to trigger on Objects.
The same issue occurs on
verify(notificationRepository, times(1)).save(not);
it does not trigger.
The questions would be:
1.) Why does the mock not trigger? I suppose it does not check for value equality in the object, but for object identifiers, which are not the same since the object is serialized and de-serialized in between.
2.) How can I get a generic mock? e.g. whenever repository.save() is called, no matter the parameter, it always should perform a specific way, e.g. instead of
when(notificationRepository.save(not)).thenReturn(not2);
I'd like to have
when(notificationRepository.save()).thenReturn(not2);
P.S. If for whatever reason you need the rest of the code, here is the submitted part, object is the json representation of the notification (with jackson)
mockMvc.perform(post("/api/notification").content(object)
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON));
and here is the Controller header, the Object is de-serialized perfectly, the values are 1:1 the same
#RequestMapping(method=RequestMethod.POST)
public ResponseEntity<?> postNotification(#RequestBody Notification n) {
logger.debug("Saving userid "+n.getId());
Thanks for helping.

1.) Why does the mock not trigger? I suppose it does not check for value equality in the object, but for object identifiers, which are not the same...
By default, Mockito delegates to your object's equals method. If you haven't overridden that, then it checks references by default. The following two lines are equivalent:
when(notificationRepository.save(not)).thenReturn(not2);
when(notificationRepository.save(not)).thenReturn(eq(not2)); // uses eq explicitly
If all Notification objects with the same fields are the same, then overriding equals and hashCode will get you where you need to go. Beware, though, that this may have unintended side-effects with regard to Set and Map behavior, especially if your Notification objects don't have an ID until they are saved.
2.) How can I get a generic mock? e.g. whenever repository.save() is called, no matter the parameter, it always should perform a specific way
With Matchers, this is very simple:
when(notificationRepository.save(not)).thenReturn(any(Notification.class));
Though Matchers are very powerful, beware: they have some tricky rules associated with their use.

For (1), as mentioned by Jeff, You might need to use eq() instead of direct reference to not1
For (2) You can use Mockito.any()
For e.g. when(notificationRepository.save(any(Notification.class))).thenReturn(not2);
This would create stubbing on mocked object notificationRepository which would always return not2 for any argument which is of type Notification. if save() method accepts Object then you can writewhen(notificationRepository.save(any(Object.class))).thenReturn(not2); which would return not2 for any argument of type Object

Related

How are request parameters mapped into RenderingModel of magnolia?

Im using Magnolia RenderingModel in combination with Freemarker.
I have URLs like the following:
http://anyPath/context?productTypes=XXXXX&productTypes=YYYYY
my rendering model class looks like:
class MyModel extends RenderingModelImpl {
...
private String[] productTypes;
...
}
However the mentioned array contains only the first value, but not the second.
I checked the behaviour of template directives like ctx.getParameters(). This shows the same behaviour, I get only the first value returned. But if im using ctx.getParameterValues(paramName), it returns both values.
This leads me to following questions:
How would I go, if I want to lookup how the request parameters are mapped into the rendering model, or better:
How can i change the behaviour of that ?
Can anyone acknowledge, that this behaviour is wrong ?
It used to be mentioned in documentation and I believe it still is - if you use .getParameters() you get only first value for multivalue parameter. If you want to get all the values, you need to use .getParameterValues(String param).
From what I understand reasons for that were backward compatibility.
As for changing the behavior, you would need to write your own renderer (e.g. by extending default FreemarkerRenderer and override info.magnolia.rendering.renderer.AbstractRenderer.newModel(Class<T>, Node, RenderableDefinition, RenderingModel<?>) method which instantiates and populates the model class.
Alternatively you can provide fix for above set population method and submit it to Magnolia as a patch. While the .getParameters() behavior is iirc on purpose, the model param population might not be, so you have high chance of getting that changed.

Using an array stored in params.yml to validate an entity

I want to validate an entity using a values stored in an array which is in the params.
What I tried to do is injecting the array from params.yml (I'm using YAML) via service into a model.
In validation.yml, I tried to use the choice constraint with a callback. but I don't know how to call a method non-static from a different class.
To do this:
- Choice: { callback: [CountryHandler, getCountries] }
getCountries must be static.
Is it possible to do something like that with a method non static? Is it a better idea* to validate the entity with my own constraint as they explain here: http://symfony.com/doc/current/cookbook/validation/custom_constraint.html?
I only have to validate one param and at first sight it doesn't seems a good idea.
I think that is a better idea because you can re-use in other case and better readability. As show in the documentation you give, you must create 2 files, one for your validator and one for the constraint, if you have dependency, you can inject to Validator declaring a new service with dependancy declared as arguments. After this, you have only to call your constraint as another Constraint.

How to test a Reducer containing a Mutation

I'm attempting to use MRUnit, but none of the examples I've seen quite match what I'm trying to do.
My reducer outputs a key and mutation, but I can't seem to compare the mutation with what's expected. It shows the objects as being the same, but with an address of 0 and the following error:
junit.framework.AssertionFailedError: expected: <org.apache.accumulo.core.data.Mutation#0> but was <org.apache.accumulo.core.data.Mutation#0>
I'm using the reduceDriver.run() method, and attempting assertEquals on my expected mutation object with the actual. Is there anything I'm missing?
Thanks for any input.
Mutation does not have an appropriate equals() implementation. you're best bet is to probably compare the results of getUpdates() and getRow(). They return a List and byte[] respectively and those are easily comparable.
Mutation has an appropriate equals() method, at least it does in the 1.4.x line. However, that method calls a private serialize() method that modifies the data about to be checked.
I've gotten around this in the past by wrapping the Mutation in a new Mutation, which calls serialize under the hood:
assertEquals(expectedMutation, new Mutation(actualMutation));
You can extend Mutation and pass the new class to mrunit. Just override equals in the new class.

Is Context.SaveChanges called automatically when an entity that is being tracked changes?

If an entities properties have changed in a controller action and Update/SaveChanges is not called, will that entity be updated automatically?
I am using EF 4.1 with a repository pattern. I handle all CRUD operations in my EfRepository class like this:
public void Update(T entity)
{
try{_context.SaveChanges();}
catch{//do stuff}
}
//etc.
In my application I have an ajax/ActionResult call that gets an entity from the db, performs some basic calculations, and returns a JSON object. To make a long story short I discovered a bug in a static helper I was using in my ActionResult that was changing a property value on my entity and not the JSON-model I was returning.
My action method has no Update methods yet my entity was being updated every time I called this action. Using Sql Profiler I confirmed an update statement that was tailored to update my entity and the one(1) property my buggy static method was changing.
I placed a break point at my Update method in my repository class and even though my entity was being updated by EF, MY Update method was never called. The summary for the interface method 'Find' (which is what I use) in IDbSet says,
Finds an entity with the given primary key values. If an entity with
the given primary key values exists in the context, then it is
returned immediately without making a request to the store. Otherwise,
a request is made to the store for an entity with the given primary
key values and this entity, if found, is attached to the context and
returned. If no entity is found in the context or the store, then null
is returned.
There are some real good example here as well.
I think given my entity was attached, the short answer to my question is 'YES'. But being somewhat new to EF I found this to be a very difficult bug to figure out as it still appears there some things going on under the covers that I could not track down. I hesitated in posting this as a question but thought someone more knowledgeable could expand on my assumed answer of YES and at the bare minimum help someone else who runs across this.
If an entities properties have changed in a controller action and
Update/SaveChanges is not called, will that entity be updated
automatically?
No, ef will only propagate your changes to the database on a SaveChanges call. Save only happens manually (IE you have to explicitly call SaveChanges).
What is really important to understand though is that SaveChanges saves all current modifications to the context. This means if you are sharing a context your changes will be saved when anyone (not just you) calls SaveChanges.

How Does Queryable.OfType Work?

Important The question is not "What does Queryable.OfType do, it's "how does the code I see there accomplish that?"
Reflecting on Queryable.OfType, I see (after some cleanup):
public static IQueryable<TResult> OfType<TResult>(this IQueryable source)
{
return (IQueryable<TResult>)source.Provider.CreateQuery(
Expression.Call(
null,
((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(
new Type[] { typeof(TResult) }) ,
new Expression[] { source.Expression }));
}
So let me see if I've got this straight:
Use reflection to grab a reference to the current method (OfType).
Make a new method, which is exactly the same, by using MakeGenericMethod to change the type parameter of the current method to, er, exactly the same thing.
The argument to that new method will be not source but source.Expression. Which isn't an IQueryable, but we'll be passing the whole thing to Expression.Call, so that's OK.
Call Expression.Call, passing null as method (weird?) instance and the cloned method as its arguments.
Pass that result to CreateQuery and cast the result, which seems like the sanest part of the whole thing.
Now the effect of this method is to return an expression which tells the provider to omit returning any values where the type is not equal to TResult or one of its subtypes. But I can't see how the steps above actually accomplish this. It seems to be creating an expression representing a method which returns IQueryable<TResult>, and making the body of that method simply the entire source expression, without ever looking at the type. Is it simply expected that an IQueryable provider will just silently not return any records not of the selected type?
So are the steps above incorrect in some way, or am I just not seeing how they result in the behavior observed at runtime?
It's not passing in null as the method - it's passing it in as the "target expression", i.e. what it's calling the method on. This is null because OfType is a static method, so it doesn't need a target.
The point of calling MakeGenericMethod is that GetCurrentMethod() returns the open version, i.e. OfType<> instead of OfType<YourType>.
Queryable.OfType itself isn't meant to contain any of the logic for omitting returning any values. That's up to the LINQ provider. The point of Queryable.OfType is to build up the expression tree to include the call to OfType, so that when the LINQ provider eventually has to convert it into its native format (e.g. SQL) it knows that OfType was called.
This is how Queryable works in general - basically it lets the provider see the whole query expression as an expression tree. That's all it's meant to do - when the provider is asked to translate this into real code, that's where the magic happens.
Queryable couldn't possibly do the work itself - it has no idea what sort of data store the provider represents. How could it come up with the semantics of OfType without knowing whether the data store was SQL, LDAP or something else? I agree it takes a while to get your head round though :)

Resources