Hi,
I would like to see an enhancement to matchers for beans so that they can
support "expressions" like OGNL
(http://commons.apache.org/proper/commons-ognl/) or Spring EL
(http://static.springsource.org/spring/docs/3.0.x/reference/expressions.html).
Motivation:
In a complex POJO, the usage of expressions could allow to test more easily
complex POJOs. Syntax would look like the following:
assertThat(myBean, hasPropertyByExp(expression, valueMatcher)
The matcher is similar to hasProperty(String propertyName, Matcher<?>
valueMatcher) but here the "expression" parameter is a String that represents
a full expression which allow querying the object graph of the bean.
As a result, asserts could be more compact and so easier to read and understand
(see the following example).
Example:
Suppose MyBean is a class with a Map<String,MyOtherBean> field named "map" and
MyOtherBean is a class with a List<String> field named list. And it is
populated like the following:
Mybean myBean = new MyBean();
myBean.setMap(new HashMap());
myBean.getMap().put("myKey", new MyOtherBean());
myBean.getMap().get("myKey").setList(Arrays.asList("one", "two", "three"));
then, if you want to test if "three" is equal to the third element of the
"list" of the instance of MyOtherBean stored under the key "myKey" in the map
"map" of the object "myBean", you could write a single line assert in the
following way:
assertThat(myBean, hasPropertyByExp("map['myKey'].list[3]", equalsTo("three"));
Technology:
I actually use Spring EL to write tests based on expression on beans. I
retrieve the value using an expression and I simply compare it with
"assertEquals".
I've written the following utility static method based on Spring EL:
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
//...
public static <T> T getValue(Object pojo, String expression, Class<T> t) {
ExpressionParser parser = new SpelExpressionParser();
Expression exp = parser.parseExpression(expression);
return exp.getValue(pojo, t);
}
If the test is embedded in a matcher, it would make the code even more readable.
General considerations to be done before implementation:
It should be considered the impact of dependencies using either Spring EL or
OGNL or other expression languages (my choice of using Spring EL has been taken
due to the fact I already have Spring dependencies on my code).
Considering that Spring EL is made also for manipulating the Object Graph, and
for testing purposes only query of the object graph is relevant, it could be
feasible also to implement a limited Expression Language specifically for
Hamcrest, and avoid external dependencies.
The following link points to the Spring EL syntax reference:
http://static.springsource.org/spring/docs/3.0.x/reference/expressions.html#expr
essions-language-ref
In particular, the most meaningful language feature of the Spring EL for
writing matchers is the syntax for querying "Properties, Arrays, Lists, Maps,
Indexers" as is described in section 6.5.2 of the previous link. Maybe this
could be implemented in Hamcrest with a little reflection and a good regex to
parse the expression.
Final note:
I've searched this feature in Hamcrest and other frameworks without success, if
I've missed it, please don't blame me and please give me a link to the
solution. I've tried to write the most precise report for the enhancement
request, if there is something which is not clear, please ask clarification in
the comments.
Thank you.
Cristiano
Original issue reported on code.google.com by cristian...@gmail.com on 28 May 2013 at 1:51
Original issue reported on code.google.com by
cristian...@gmail.com
on 28 May 2013 at 1:51