-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Description
Overview
I have found that it would be useful if you could use argument fields as a part of parametrized test name. Right now, when using just {0}
as described in docs, it results in injecting into a test name string in form of ClassName(fieldName1=fieldValue1, fieldName2=fieldValue2, ...)
. But that doesn't seen readable at all especially then you have a class with more than just few fields. Now I would like to be able to use some semantics as {0.name}
or {0}.name
to use just name field of class used as test method argument, so I can write test name as follows:
@BeerTest
class BeerConversionServiceTest {
@Autowired
private BeerConversionService beerConversionService;
private static Stream<Arguments> createBeers() {
return Stream.of(
Arguments.of(new Beer(...), 25L),
Arguments.of(new Beer(...), 50L)
);
}
@DisplayName("Get alcohol content of a beer in mg")
@ParameterizedTest(name = "Alcohol content of {0.name} should be equal to {1}")
@MethodSource("createBeers")
void getAlcInMg(Beer beer, long mg) {
Assertions.assertEquals(beerConversionService.getAlcInMg(beer), mg);
}
}
This would give users possibility to keep test names simple, yet still descriptive, as they could reference objects passed as arguments and use only parts of them which identifies test cases.
I didn't look into the source code so I cannot tell which approach would be easier to implement but I would guess that {0.name}
seems more reasonable.
Deliverables
- Introduce an SPI (similar to what has been proposed above) and provide a SpEL-based and/or OGNL-based implementation.Ensure that display names for
@ParameterizedTest
and@RepeatedTest
can make use of the same facility (see @ParameterizedTest display custom names for arguments #2452).To pick up a draggable item, press the space bar. While dragging, use the arrow keys to move the item. Press space again to drop the item in its new position, or press escape to cancel.
Activity
marcphilipp commentedon Nov 11, 2017
I agree that this would be useful. Implementation-wise it might be a rabbit hole, though. We should probably check for getters first. If there are none, we could try to find a field traversing the class hierarchy upward.
@junit-team/junit-lambda Thoughts?
vikaskumar89 commentedon Nov 17, 2017
hi @marcphilipp may i please work on this?
marcphilipp commentedon Nov 17, 2017
Sure!
sbrannen commentedon Nov 17, 2017
name()
getName()
name
(local and then traversing the hierarchy)DcortezMeleth commentedon Nov 17, 2017
Seems like a good idea.
sormuras commentedon Nov 17, 2017
How about supporting
{{ mustache }}
notation? We could include this library here https://github.com/spullara/mustache.javamarcphilipp commentedon Nov 17, 2017
I was also wondering about that. If we do, it needs to be an extension, though. Moreover, I'm not sure we need everything mustache has to offer. 🤔
DcortezMeleth commentedon Nov 17, 2017
Mustache may be a nice addition but I agree with Mark that if it's going to be used it should be provided as some kind of extension because it will be used by rather small amount of users.
But will we need anything apart of this simple usecase? If not, additional dependecy seems a bit unnecessary.
marcphilipp commentedon Nov 17, 2017
Do we want to support things like
{0.manufacturer.owner.name}
?sbrannen commentedon Nov 18, 2017
Based on the discussions here, I think it's already starting to get a bit out of hand.
As soon as we support one level of expressions, people will want more, and then they'll want additional features that the JUnit Team should not be implementing (due to scope).
So, in order to avoid feature creep, my proposal is to go back to the original plan (from the JUnit Lambda prototype phase) to add an extension for plugging in a custom expression language.
See also:
In summary, I believe it would be better to design a new extension API that receives the
String displayName
and aMap<String,Object> expressionContextMap
and then allow people to pick between Mustache, SpEL, etc.sbrannen commentedon Nov 18, 2017
For example...
"Owner: {0.manufacturer.owner.name}"
."Owner: #{#0.manufacturer.owner.name}"
or"Owner: #{#beer.manufacturer.owner.name}"
.47 remaining items