Skip to content

Commit e7613a7

Browse files
authored
Create README.md (#1)
* Create README.md * Update README.md * Update README.md
1 parent f0d0267 commit e7613a7

File tree

1 file changed

+97
-0
lines changed

1 file changed

+97
-0
lines changed

README.md

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
# Snapshot testing with Java
2+
_Avoid serial assertions when testing serializable objects._
3+
4+
## Simple usage
5+
```java
6+
@Test
7+
public void test() {
8+
String s = "StringToTest";
9+
10+
assertThat(s, matchesSnapshot());
11+
}
12+
```
13+
On the first execution of this test, it will generate a snapshot file in resources folder. This file looks like this:
14+
```json
15+
"StringToTest"
16+
```
17+
This file **must be committed**.
18+
Next executions of this test will read said file and compare with actual value.
19+
20+
Assertion will fail if serialized values are different.
21+
22+
We use [Jackson](https://github.com/FasterXML/jackson) to handle serialization/deserialization to JSON format.
23+
This library therefore can handle any object that is serializable by Jackson.
24+
25+
## Real world example
26+
Full example available [here](https://github.com/Zenika/java-snapshot-matcher/tree/master/snapshot-matcher-example).
27+
28+
I want to test a converter, which transforms a `Planet` into a `PlanetDTO`.
29+
```java
30+
@Component
31+
public class PlanetConverter {
32+
33+
@Autowired
34+
private ObjectMapper objectMapper;
35+
36+
@Autowired
37+
private RestTemplate restTemplate;
38+
39+
public PlanetDTO convertPlanet(Planet planet) {
40+
PlanetDTO dto = objectMapper.convertValue(planet, PlanetDTO.class);
41+
42+
dto.films = planet.filmsUrls.stream()
43+
.map(filmUrl -> restTemplate.getForObject(filmUrl, FilmDTO.class))
44+
.collect(Collectors.toList());
45+
46+
dto.residents = planet.residentsUrls.stream()
47+
.map(filmUrl -> restTemplate.getForObject(filmUrl, PeopleDTO.class))
48+
.collect(Collectors.toList());
49+
50+
return dto;
51+
}
52+
}
53+
```
54+
55+
As it can be difficult to generate input object and to perform assertions on returned object, we use the snapshot matcher to handle assertions.
56+
57+
```java
58+
@RunWith(SpringRunner.class)
59+
@SpringBootTest
60+
public class PlanetConverterTest {
61+
62+
// RestTemplate needs to be mocked to ensure stability of snapshots.
63+
// Note that ObjectMapper is not mocked
64+
@Mock
65+
private RestTemplate restTemplate;
66+
67+
@Autowired
68+
@InjectMocks
69+
private PlanetConverter converter;
70+
71+
// Create input objects from JSON files
72+
private PeopleDTO lukeSkywalker = fromJson("luke-skywalker", PeopleDTO.class);
73+
private FilmDTO attackOfTheClones = fromJson("attack-of-the-clones", FilmDTO.class);
74+
private Planet tatooine = fromJson("tatooine", Planet.class);
75+
76+
@Before
77+
public void setUp() {
78+
// Mock return values of RestTemplate
79+
when(restTemplate.getForObject("https://swapi.co/api/people/1/", PeopleDTO.class))
80+
.thenReturn(lukeSkywalker);
81+
when(restTemplate.getForObject("https://swapi.co/api/films/5/", FilmDTO.class))
82+
.thenReturn(attackOfTheClones);
83+
}
84+
85+
@Test
86+
public void converterTest() {
87+
// Call method
88+
PlanetDTO planet = converter.convertPlanet(tatooine);
89+
90+
// Do assertion
91+
assertThat(planet, matchesSnapshot());
92+
}
93+
}
94+
```
95+
96+
## Limitations
97+
- Only one snapshot assertion per test method

0 commit comments

Comments
 (0)