Skip to content

Commit 826776f

Browse files
committed
Improve assertions in DefaultConversionServiceTests
Specifically, we now check the actual type of a converted collection in various assertions to ensure that converters adhere to their contracts.
1 parent 29f92c8 commit 826776f

File tree

1 file changed

+68
-79
lines changed

1 file changed

+68
-79
lines changed

spring-core/src/test/java/org/springframework/core/convert/converter/DefaultConversionServiceTests.java

Lines changed: 68 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454

5555
import static org.assertj.core.api.Assertions.assertThat;
5656
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
57+
import static org.assertj.core.api.Assertions.entry;
5758

5859
/**
5960
* Unit tests for {@link DefaultConversionService}.
@@ -324,8 +325,8 @@ void numberToNumber() {
324325

325326
@Test
326327
void numberToNumberNotSupportedNumber() {
327-
assertThatExceptionOfType(ConversionFailedException.class).isThrownBy(() ->
328-
conversionService.convert(1, CustomNumber.class));
328+
assertThatExceptionOfType(ConversionFailedException.class)
329+
.isThrownBy(() -> conversionService.convert(1, CustomNumber.class));
329330
}
330331

331332
@Test
@@ -342,44 +343,45 @@ void characterToNumber() {
342343

343344
@Test
344345
void convertArrayToCollectionInterface() {
345-
Collection<?> result = conversionService.convert(new String[] {"1", "2", "3"}, Collection.class);
346-
assertThat(result).isEqualTo(Set.of("1", "2", "3"));
346+
@SuppressWarnings("unchecked")
347+
Collection<String> result = conversionService.convert(new String[] {"1", "2", "3"}, Collection.class);
348+
assertThat(result).isExactlyInstanceOf(LinkedHashSet.class).containsExactly("1", "2", "3");
347349
}
348350

349351
@Test
350352
void convertArrayToSetInterface() {
351-
Collection<?> result = conversionService.convert(new String[] {"1", "2", "3"}, Set.class);
352-
assertThat(result).isEqualTo(Set.of("1", "2", "3"));
353+
@SuppressWarnings("unchecked")
354+
Collection<String> result = conversionService.convert(new String[] {"1", "2", "3"}, Set.class);
355+
assertThat(result).isExactlyInstanceOf(LinkedHashSet.class).containsExactly("1", "2", "3");
353356
}
354357

355358
@Test
356359
void convertArrayToListInterface() {
357-
List<?> result = conversionService.convert(new String[] {"1", "2", "3"}, List.class);
358-
assertThat(result).isEqualTo(List.of("1", "2", "3"));
360+
@SuppressWarnings("unchecked")
361+
List<String> result = conversionService.convert(new String[] {"1", "2", "3"}, List.class);
362+
assertThat(result).isExactlyInstanceOf(ArrayList.class).containsExactly("1", "2", "3");
359363
}
360364

361365
@Test
362366
void convertArrayToCollectionGenericTypeConversion() throws Exception {
363367
@SuppressWarnings("unchecked")
364-
List<Integer> result = (List<Integer>) conversionService.convert(new String[] {"1", "2", "3"}, TypeDescriptor
365-
.valueOf(String[].class), new TypeDescriptor(getClass().getDeclaredField("genericList")));
366-
assertThat(result).isEqualTo(List.of(1, 2, 3));
368+
List<Integer> result = (List<Integer>) conversionService.convert(new String[] {"1", "2", "3"},
369+
TypeDescriptor.valueOf(String[].class), new TypeDescriptor(getClass().getDeclaredField("genericList")));
370+
assertThat(result).isExactlyInstanceOf(ArrayList.class).containsExactly(1, 2, 3);
367371
}
368372

369373
@Test
370374
void convertArrayToStream() throws Exception {
371375
String[] source = {"1", "3", "4"};
372376
@SuppressWarnings("unchecked")
373377
Stream<Integer> result = (Stream<Integer>) this.conversionService.convert(source,
374-
TypeDescriptor.valueOf(String[].class),
375-
new TypeDescriptor(getClass().getDeclaredField("genericStream")));
378+
TypeDescriptor.valueOf(String[].class), new TypeDescriptor(getClass().getDeclaredField("genericStream")));
376379
assertThat(result).containsExactly(1, 3, 4);
377380
}
378381

379382
@Test
380383
void spr7766() throws Exception {
381-
ConverterRegistry registry = (conversionService);
382-
registry.addConverter(new ColorConverter());
384+
conversionService.addConverter(new ColorConverter());
383385
@SuppressWarnings("unchecked")
384386
List<Color> colors = (List<Color>) conversionService.convert(new String[] {"ffffff", "#000000"},
385387
TypeDescriptor.valueOf(String[].class),
@@ -389,14 +391,15 @@ void spr7766() throws Exception {
389391

390392
@Test
391393
void convertArrayToCollectionImpl() {
392-
ArrayList<?> result = conversionService.convert(new String[] {"1", "2", "3"}, ArrayList.class);
393-
assertThat(result).isEqualTo(List.of("1", "2", "3"));
394+
@SuppressWarnings("unchecked")
395+
ArrayList<String> result = conversionService.convert(new String[] {"1", "2", "3"}, ArrayList.class);
396+
assertThat(result).isExactlyInstanceOf(ArrayList.class).containsExactly("1", "2", "3");
394397
}
395398

396399
@Test
397400
void convertArrayToAbstractCollection() {
398-
assertThatExceptionOfType(ConversionFailedException.class).isThrownBy(() ->
399-
conversionService.convert(new String[]{"1", "2", "3"}, AbstractList.class));
401+
assertThatExceptionOfType(ConversionFailedException.class)
402+
.isThrownBy(() -> conversionService.convert(new String[]{"1", "2", "3"}, AbstractList.class));
400403
}
401404

402405
@Test
@@ -465,8 +468,7 @@ void convertArrayToObjectAssignableTargetType() {
465468
@Test
466469
void convertObjectToArray() {
467470
Object[] result = conversionService.convert(3L, Object[].class);
468-
assertThat(result).hasSize(1);
469-
assertThat(result[0]).isEqualTo(3L);
471+
assertThat(result).containsExactly(3L);
470472
}
471473

472474
@Test
@@ -506,15 +508,17 @@ void convertCollectionToStringWithElementConversion() throws Exception {
506508

507509
@Test
508510
void convertStringToCollection() {
509-
List<?> result = conversionService.convert("1,2,3", List.class);
510-
assertThat(result).isEqualTo(List.of("1", "2", "3"));
511+
@SuppressWarnings("unchecked")
512+
List<String> result = conversionService.convert("1,2,3", List.class);
513+
assertThat(result).containsExactly("1", "2", "3");
511514
}
512515

513516
@Test
514517
void convertStringToCollectionWithElementConversion() throws Exception {
515-
List<?> result = (List<?>) conversionService.convert("1,2,3", TypeDescriptor.valueOf(String.class),
518+
@SuppressWarnings("unchecked")
519+
List<Integer> result = (List<Integer>) conversionService.convert("1,2,3", TypeDescriptor.valueOf(String.class),
516520
new TypeDescriptor(getClass().getField("genericList")));
517-
assertThat(result).isEqualTo(List.of(1, 2, 3));
521+
assertThat(result).containsExactly(1, 2, 3);
518522
}
519523

520524
@Test
@@ -539,26 +543,24 @@ void convertCollectionToObjectWithElementConversion() {
539543

540544
@Test
541545
void convertCollectionToObjectAssignableTarget() throws Exception {
542-
Collection<String> source = new ArrayList<>();
543-
source.add("foo");
546+
Collection<String> source = List.of("foo");
544547
Object result = conversionService.convert(source, new TypeDescriptor(getClass().getField("assignableTarget")));
545-
assertThat(result).isEqualTo(source);
548+
assertThat(result).isSameAs(source);
546549
}
547550

548551
@Test
549552
void convertCollectionToObjectWithCustomConverter() {
550-
List<String> source = new ArrayList<>();
551-
source.add("A");
552-
source.add("B");
553+
List<String> source = List.of("A", "B");
553554
conversionService.addConverter(List.class, ListWrapper.class, ListWrapper::new);
554555
ListWrapper result = conversionService.convert(source, ListWrapper.class);
555556
assertThat(result.getList()).isSameAs(source);
556557
}
557558

558559
@Test
559560
void convertObjectToCollection() {
560-
List<?> result = conversionService.convert(3L, List.class);
561-
assertThat(result).isEqualTo(List.of(3L));
561+
@SuppressWarnings("unchecked")
562+
List<Long> result = conversionService.convert(3L, List.class);
563+
assertThat(result).containsExactly(3L);
562564
}
563565

564566
@Test
@@ -607,7 +609,7 @@ void convertObjectArrayToIntArray() {
607609

608610
@Test
609611
void convertByteArrayToWrapperArray() {
610-
byte[] byteArray = new byte[] {1, 2, 3};
612+
byte[] byteArray = {1, 2, 3};
611613
Byte[] converted = conversionService.convert(byteArray, Byte[].class);
612614
assertThat(converted).isEqualTo(new Byte[]{1, 2, 3});
613615
}
@@ -667,21 +669,18 @@ void convertCollectionToCollectionNull() throws Exception {
667669
@SuppressWarnings("unchecked")
668670
List<Integer> bar = (List<Integer>) conversionService.convert(null,
669671
TypeDescriptor.valueOf(LinkedHashSet.class), new TypeDescriptor(getClass().getField("genericList")));
670-
assertThat((Object) bar).isNull();
672+
assertThat(bar).isNull();
671673
}
672674

673675
@Test
674-
@SuppressWarnings("rawtypes")
676+
@SuppressWarnings({ "rawtypes", "unchecked" })
675677
void convertCollectionToCollectionNotGeneric() {
676678
Set<String> foo = new LinkedHashSet<>();
677679
foo.add("1");
678680
foo.add("2");
679681
foo.add("3");
680-
List bar = (List) conversionService.convert(foo, TypeDescriptor.valueOf(LinkedHashSet.class), TypeDescriptor
681-
.valueOf(List.class));
682-
assertThat(bar.get(0)).isEqualTo("1");
683-
assertThat(bar.get(1)).isEqualTo("2");
684-
assertThat(bar.get(2)).isEqualTo("3");
682+
List bar = (List) conversionService.convert(foo, TypeDescriptor.valueOf(LinkedHashSet.class), TypeDescriptor.valueOf(List.class));
683+
assertThat(bar).containsExactly("1", "2", "3");
685684
}
686685

687686
@Test
@@ -694,43 +693,35 @@ void convertCollectionToCollectionSpecialCaseSourceImpl() throws Exception {
694693
Collection values = map.values();
695694
List<Integer> bar = (List<Integer>) conversionService.convert(values,
696695
TypeDescriptor.forObject(values), new TypeDescriptor(getClass().getField("genericList")));
697-
assertThat(bar).hasSize(3);
698-
assertThat(bar.get(0)).isEqualTo(1);
699-
assertThat(bar.get(1)).isEqualTo(2);
700-
assertThat(bar.get(2)).isEqualTo(3);
696+
assertThat(bar).containsExactly(1, 2, 3);
701697
}
702698

703699
@Test
704700
void collection() {
705-
List<String> strings = new ArrayList<>();
706-
strings.add("3");
707-
strings.add("9");
701+
List<String> strings = List.of("3", "9");
708702
@SuppressWarnings("unchecked")
709703
List<Integer> integers = (List<Integer>) conversionService.convert(strings,
710704
TypeDescriptor.collection(List.class, TypeDescriptor.valueOf(Integer.class)));
711-
assertThat(integers.get(0)).isEqualTo(3);
712-
assertThat(integers.get(1)).isEqualTo(9);
705+
assertThat(integers).containsExactly(3, 9);
713706
}
714707

715708
@Test
716709
void convertMapToMap() throws Exception {
717-
Map<String, String> foo = new HashMap<>();
718-
foo.put("1", "BAR");
719-
foo.put("2", "BAZ");
710+
Map<String, String> foo = Map.of("1", "BAR", "2", "BAZ");
720711
@SuppressWarnings("unchecked")
721712
Map<Integer, Foo> map = (Map<Integer, Foo>) conversionService.convert(foo,
722713
TypeDescriptor.forObject(foo), new TypeDescriptor(getClass().getField("genericMap")));
723-
assertThat(map.get(1)).isEqualTo(Foo.BAR);
724-
assertThat(map.get(2)).isEqualTo(Foo.BAZ);
714+
assertThat(map).contains(entry(1, Foo.BAR), entry(2, Foo.BAZ));
725715
}
726716

727717
@Test
728718
void convertHashMapValuesToList() {
729719
Map<String, Integer> hashMap = new LinkedHashMap<>();
730720
hashMap.put("1", 1);
731721
hashMap.put("2", 2);
732-
List<?> converted = conversionService.convert(hashMap.values(), List.class);
733-
assertThat(converted).isEqualTo(List.of(1, 2));
722+
@SuppressWarnings("unchecked")
723+
List<Integer> converted = conversionService.convert(hashMap.values(), List.class);
724+
assertThat(converted).containsExactly(1, 2);
734725
}
735726

736727
@Test
@@ -741,8 +732,7 @@ void map() {
741732
@SuppressWarnings("unchecked")
742733
Map<Integer, Integer> integers = (Map<Integer, Integer>) conversionService.convert(strings,
743734
TypeDescriptor.map(Map.class, TypeDescriptor.valueOf(Integer.class), TypeDescriptor.valueOf(Integer.class)));
744-
assertThat(integers.get(3)).isEqualTo(9);
745-
assertThat(integers.get(6)).isEqualTo(31);
735+
assertThat(integers).contains(entry(3, 9), entry(6, 31));
746736
}
747737

748738
@Test
@@ -751,25 +741,25 @@ void convertPropertiesToString() {
751741
foo.setProperty("1", "BAR");
752742
foo.setProperty("2", "BAZ");
753743
String result = conversionService.convert(foo, String.class);
754-
assertThat(result).contains("1=BAR");
755-
assertThat(result).contains("2=BAZ");
744+
assertThat(result).contains("1=BAR", "2=BAZ");
756745
}
757746

758747
@Test
759748
void convertStringToProperties() {
760-
Properties result = conversionService.convert("a=b\nc=2\nd=", Properties.class);
761-
assertThat(result).hasSize(3);
762-
assertThat(result.getProperty("a")).isEqualTo("b");
763-
assertThat(result.getProperty("c")).isEqualTo("2");
764-
assertThat(result.getProperty("d")).isEmpty();
749+
Properties result = conversionService.convert("""
750+
a=b
751+
c=2
752+
d=""", Properties.class);
753+
assertThat(result).contains(entry("a", "b"), entry("c", "2"), entry("d", ""));
765754
}
766755

767756
@Test
768-
void convertStringToPropertiesWithSpaces() {
769-
Properties result = conversionService.convert(" foo=bar\n bar=baz\n baz=boop", Properties.class);
770-
assertThat(result.get("foo")).isEqualTo("bar");
771-
assertThat(result.get("bar")).isEqualTo("baz");
772-
assertThat(result.get("baz")).isEqualTo("boop");
757+
void convertStringToPropertiesWithLeadingSpaces() {
758+
Properties result = conversionService.convert("""
759+
\s foo=bar
760+
\s bar=baz
761+
\s baz=boo""", Properties.class);
762+
assertThat(result).contains(entry("foo", "bar"), entry("bar", "baz"), entry("baz", "boo"));
773763
}
774764

775765
// generic object conversion
@@ -838,8 +828,8 @@ void convertObjectToObjectWithJavaTimeOfMethod() {
838828

839829
@Test
840830
void convertObjectToObjectNoValueOfMethodOrConstructor() {
841-
assertThatExceptionOfType(ConverterNotFoundException.class).isThrownBy(() ->
842-
conversionService.convert(3L, SSN.class));
831+
assertThatExceptionOfType(ConverterNotFoundException.class)
832+
.isThrownBy(() -> conversionService.convert(3L, SSN.class));
843833
}
844834

845835
@Test
@@ -870,21 +860,20 @@ void convertCharArrayToString() {
870860
@Test
871861
void convertStringToCharArray() {
872862
char[] converted = conversionService.convert("a,b,c", char[].class);
873-
assertThat(converted).isEqualTo(new char[]{'a', 'b', 'c'});
863+
assertThat(converted).containsExactly('a', 'b', 'c');
874864
}
875865

876866
@Test
877867
void convertStringToCustomCharArray() {
878868
conversionService.addConverter(String.class, char[].class, String::toCharArray);
879869
char[] converted = conversionService.convert("abc", char[].class);
880-
assertThat(converted).isEqualTo(new char[] {'a', 'b', 'c'});
870+
assertThat(converted).containsExactly('a', 'b', 'c');
881871
}
882872

883873
@Test
884874
@SuppressWarnings("unchecked")
885875
void multidimensionalArrayToListConversionShouldConvertEntriesCorrectly() {
886-
String[][] grid = new String[][] {new String[] {"1", "2", "3", "4"}, new String[] {"5", "6", "7", "8"},
887-
new String[] {"9", "10", "11", "12"}};
876+
String[][] grid = new String[][] {{"1", "2", "3", "4"}, {"5", "6", "7", "8"}, {"9", "10", "11", "12"}};
888877
List<String[]> converted = conversionService.convert(grid, List.class);
889878
String[][] convertedBack = conversionService.convert(converted, String[][].class);
890879
assertThat(convertedBack).isEqualTo(grid);
@@ -893,10 +882,10 @@ void multidimensionalArrayToListConversionShouldConvertEntriesCorrectly() {
893882
@Test
894883
void convertCannotOptimizeArray() {
895884
conversionService.addConverter(Byte.class, Byte.class, source -> (byte) (source + 1));
896-
byte[] byteArray = new byte[] {1, 2, 3};
885+
byte[] byteArray = {1, 2, 3};
897886
byte[] converted = conversionService.convert(byteArray, byte[].class);
898887
assertThat(converted).isNotSameAs(byteArray);
899-
assertThat(converted).isEqualTo(new byte[]{2, 3, 4});
888+
assertThat(converted).containsExactly(2, 3, 4);
900889
}
901890

902891
@Test

0 commit comments

Comments
 (0)