Skip to content

Commit c95b877

Browse files
committed
Test to cover all basic functionality
1 parent a624c18 commit c95b877

17 files changed

Lines changed: 473 additions & 116 deletions

src/main/java/pl/wavesoftware/utils/mapstruct/jpa/MappingsBuilderImpl.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ public <I, O, C> Mapping<I,O,C> getMapping(Class<I> sourceClass,
4040
}
4141
throw new EidIllegalStateException(
4242
new Eid("20180425:135245"),
43-
"AbstractMapping for source class %s and target class %s is not configured!",
43+
"Mapping for source class %s and target class %s is not configured!",
4444
sourceClass.getName(), targetClass.getName()
4545
);
4646
}

src/test/java/pl/wavesoftware/test/MappingTest.java

Lines changed: 95 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,19 @@
33
import com.google.inject.Guice;
44
import com.google.inject.Injector;
55
import com.google.inject.Module;
6+
import lombok.RequiredArgsConstructor;
67
import org.junit.Rule;
78
import org.junit.Test;
9+
import org.junit.rules.ExpectedException;
810
import org.mockito.Mock;
11+
import org.mockito.invocation.InvocationOnMock;
912
import org.mockito.junit.MockitoJUnit;
1013
import org.mockito.junit.MockitoRule;
14+
import org.mockito.stubbing.Answer;
15+
import pl.wavesoftware.eid.exceptions.EidIllegalStateException;
16+
import pl.wavesoftware.test.TestRepository.Database;
17+
import pl.wavesoftware.test.TestRepository.Example;
18+
import pl.wavesoftware.test.TestRepository.Execution;
1119
import pl.wavesoftware.test.entity.Pet;
1220
import pl.wavesoftware.test.jpa.PetJPA;
1321
import pl.wavesoftware.test.mapper.MapperFacade;
@@ -16,8 +24,12 @@
1624
import java.util.ArrayList;
1725
import java.util.Arrays;
1826
import java.util.List;
27+
import java.util.Optional;
1928

2029
import static org.assertj.core.api.Assertions.assertThat;
30+
import static org.mockito.ArgumentMatchers.any;
31+
import static org.mockito.ArgumentMatchers.anyLong;
32+
import static org.mockito.Mockito.when;
2133

2234
/**
2335
* @author <a href="mailto:krzysztof.suszynski@wavesoftware.pl">Krzysztof Suszynski</a>
@@ -33,14 +45,23 @@ public class MappingTest {
3345
@Rule
3446
public MockitoRule mockitoRule = MockitoJUnit.rule();
3547

48+
@Rule
49+
public ExpectedException thrown = ExpectedException.none();
50+
3651
@Test
3752
public void testMapFromPetToJPA() {
3853
// given
3954
Injector injector = createInjector((Module) binder ->
4055
binder.bind(EntityManager.class).toInstance(entityManager)
4156
);
4257
MapperFacade mapper = injector.getInstance(MapperFacade.class);
43-
Pet alice = testRepository.createPetNamedAlice();
58+
Execution execution = testRepository.forCase(Example.STANDARD);
59+
Database<Pet> entityDb = execution.createPetNamedAlice();
60+
Database<PetJPA> database = execution.createJpaPetNamedAlice();
61+
bindEntityManager(database);
62+
Pet alice = entityDb.getObject();
63+
Optional.ofNullable(alice.getOwner())
64+
.ifPresent(o -> o.setName("John Wick"));
4465

4566
// when
4667
PetJPA aliceJpa = mapper.map(alice);
@@ -49,6 +70,68 @@ public void testMapFromPetToJPA() {
4970
assertThat(alice).isNotNull();
5071
assertThat(aliceJpa).isNotNull();
5172
assertThat(mapper).isNotNull();
73+
assertThat(aliceJpa.getId()).isEqualTo(TestRepository.ALICE_ID);
74+
assertThat(alice.getOwner()).isNotNull();
75+
assertThat(aliceJpa.getOwner().getName()).isEqualTo(TestRepository.OWNER_NAME);
76+
assertThat(aliceJpa.getOwner().getSurname()).isEqualTo("Wick");
77+
}
78+
79+
@Test
80+
public void testMapFromJPAToPet() {
81+
// given
82+
Injector injector = createInjector((Module) binder ->
83+
binder.bind(EntityManager.class).toInstance(entityManager)
84+
);
85+
MapperFacade mapper = injector.getInstance(MapperFacade.class);
86+
Database<PetJPA> database = testRepository
87+
.forCase(Example.STANDARD)
88+
.createJpaPetNamedAlice();
89+
PetJPA aliceJpa = database.getObject();
90+
91+
// when
92+
Pet alice = mapper.map(aliceJpa);
93+
94+
// then
95+
assertThat(alice).isNotNull();
96+
assertThat(aliceJpa).isNotNull();
97+
assertThat(mapper).isNotNull();
98+
assertThat(alice.getReference()).isEqualTo(TestRepository.ALICE_ID);
99+
assertThat(alice.getOwner()).isNotNull();
100+
assertThat(alice.getOwner().getReference())
101+
.isEqualTo(TestRepository.OWNER_ID);
102+
assertThat(alice.getOwner().getName())
103+
.isEqualTo(TestRepository.OWNER_NAME + " " + TestRepository.OWNER_SURNAME);
104+
}
105+
106+
@Test
107+
public void testMissingMappingForToy() {
108+
// given
109+
Injector injector = createInjector((Module) binder ->
110+
binder.bind(EntityManager.class).toInstance(entityManager)
111+
);
112+
MapperFacade mapper = injector.getInstance(MapperFacade.class);
113+
Execution execution = testRepository.forCase(Example.WITH_TOY);
114+
Database<Pet> entityDb = execution.createPetNamedAlice();
115+
Database<PetJPA> database = execution.createJpaPetNamedAlice();
116+
bindEntityManager(database);
117+
Pet alice = entityDb.getObject();
118+
119+
// then
120+
assertThat(alice).isNotNull();
121+
assertThat(mapper).isNotNull();
122+
thrown.expect(EidIllegalStateException.class);
123+
thrown.expectMessage("20180425:135245");
124+
thrown.expectMessage("Mapping for source class pl.wavesoftware.test.entity.Toy " +
125+
"and target class pl.wavesoftware.test.jpa.ToyJPA is not configured!");
126+
127+
// when
128+
mapper.map(alice);
129+
}
130+
131+
private void bindEntityManager(Database<?> database) {
132+
Class<?> cls = any(Class.class);
133+
when(entityManager.find(cls, anyLong()))
134+
.thenAnswer(new EntityManagerAnswer(database));
52135
}
53136

54137
private Injector createInjector(Module... modules) {
@@ -57,4 +140,15 @@ private Injector createInjector(Module... modules) {
57140
allModules.addAll(Arrays.asList(modules));
58141
return Guice.createInjector(allModules);
59142
}
143+
144+
@RequiredArgsConstructor
145+
private static final class EntityManagerAnswer implements Answer<Object> {
146+
private final Database<?> database;
147+
@Override
148+
public Object answer(InvocationOnMock invocationOnMock) {
149+
Class<?> cls = invocationOnMock.getArgument(0);
150+
Object id = invocationOnMock.getArgument(1);
151+
return database.find(cls, id);
152+
}
153+
}
60154
}
Lines changed: 176 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,188 @@
11
package pl.wavesoftware.test;
22

3+
import lombok.AccessLevel;
4+
import lombok.RequiredArgsConstructor;
5+
import pl.wavesoftware.test.entity.AbstractEntity;
36
import pl.wavesoftware.test.entity.Owner;
47
import pl.wavesoftware.test.entity.Pet;
8+
import pl.wavesoftware.test.entity.Toy;
9+
import pl.wavesoftware.test.jpa.AbstractRecord;
10+
import pl.wavesoftware.test.jpa.OwnerJPA;
11+
import pl.wavesoftware.test.jpa.PetJPA;
12+
import pl.wavesoftware.test.jpa.ToyJPA;
13+
14+
import javax.annotation.Nullable;
15+
import java.util.Arrays;
16+
import java.util.HashMap;
17+
import java.util.LinkedHashSet;
18+
import java.util.Map;
19+
import java.util.Optional;
20+
import java.util.Set;
21+
import java.util.function.Function;
22+
23+
import static pl.wavesoftware.eid.utils.EidPreconditions.checkNotNull;
524

625
/**
726
* @author <a href="mailto:krzysztof.suszynski@wavesoftware.pl">Krzysztof Suszynski</a>
827
* @since 04.05.18
928
*/
1029
final class TestRepository {
11-
Pet createPetNamedAlice() {
12-
Pet alice = new Pet();
13-
alice.setName("Alice");
14-
Owner owner = new Owner();
15-
alice.setOwner(owner);
16-
17-
Pet kitie = new Pet();
18-
kitie.setName("Kitie");
19-
20-
owner.getPets().add(alice);
21-
owner.getPets().add(kitie);
22-
return alice;
30+
31+
static final long ALICE_ID = 14L;
32+
private static final String KITIE_NAME = "Kitie";
33+
34+
private static final long KITIE_ID = 15L;
35+
private static final String ALICE_NAME = "Alice";
36+
37+
static final Long OWNER_ID = 16L;
38+
static final String OWNER_NAME = "John";
39+
static final String OWNER_SURNAME = "Doe";
40+
41+
private static final Long TOY_ID = 17L;
42+
43+
Execution forCase(Example example) {
44+
return new ExampledExecution(example);
45+
}
46+
47+
enum Example {
48+
STANDARD,
49+
WITH_TOY
50+
}
51+
52+
interface Execution {
53+
Database<Pet> createPetNamedAlice();
54+
Database<PetJPA> createJpaPetNamedAlice();
55+
}
56+
57+
interface Database<T> {
58+
T getObject();
59+
@Nullable
60+
<E> E find(Class<?> cls, Object id);
61+
}
62+
63+
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
64+
private static final class ExampledExecution implements Execution {
65+
private final Example example;
66+
67+
@Override
68+
public Database<Pet> createPetNamedAlice() {
69+
Pet alice = new Pet();
70+
alice.setReference(ALICE_ID);
71+
alice.setName(ALICE_NAME);
72+
Owner owner = new Owner();
73+
owner.setReference(OWNER_ID);
74+
owner.setName(OWNER_NAME + " " + OWNER_SURNAME);
75+
76+
Pet kitie = new Pet();
77+
kitie.setReference(KITIE_ID);
78+
kitie.setName(KITIE_NAME);
79+
80+
alice.setOwner(owner);
81+
owner.getPets().addAll(Arrays.asList(alice, kitie));
82+
83+
DatabaseImpl<Pet> db = new DatabaseImpl<>(alice, candidate -> {
84+
if (candidate instanceof AbstractEntity) {
85+
return Optional.ofNullable(
86+
AbstractEntity.class.cast(candidate).getReference()
87+
);
88+
}
89+
return Optional.empty();
90+
});
91+
92+
if (example == Example.WITH_TOY) {
93+
Toy toy = new Toy("ball");
94+
toy.setReference(TOY_ID);
95+
kitie.setToy(toy);
96+
db.add(toy);
97+
}
98+
99+
db.add(kitie);
100+
db.add(owner);
101+
return db;
102+
}
103+
104+
@Override
105+
public Database<PetJPA> createJpaPetNamedAlice() {
106+
PetJPA alice = new PetJPA();
107+
alice.setId(ALICE_ID);
108+
alice.setName(ALICE_NAME);
109+
110+
PetJPA kitie = new PetJPA();
111+
kitie.setId(KITIE_ID);
112+
kitie.setName(KITIE_NAME);
113+
114+
OwnerJPA owner = new OwnerJPA();
115+
owner.setId(OWNER_ID);
116+
owner.setName(OWNER_NAME);
117+
owner.setSurname(OWNER_SURNAME);
118+
119+
alice.setOwner(owner);
120+
owner.getPets().addAll(Arrays.asList(alice, kitie));
121+
122+
DatabaseImpl<PetJPA> db = new DatabaseImpl<>(alice, candidate -> {
123+
if (candidate instanceof AbstractRecord) {
124+
return Optional.ofNullable(
125+
AbstractRecord.class.cast(candidate).getId()
126+
);
127+
}
128+
return Optional.empty();
129+
});
130+
131+
if (example == Example.WITH_TOY) {
132+
ToyJPA toy = new ToyJPA("ball");
133+
toy.setId(TOY_ID);
134+
kitie.setToy(toy);
135+
db.add(toy);
136+
}
137+
138+
db.add(kitie);
139+
db.add(owner);
140+
return db;
141+
}
142+
}
143+
144+
private static final class DatabaseImpl<T> implements Database<T> {
145+
146+
private final Map<Class<?>, Set<?>> objects = new HashMap<>();
147+
private final T entity;
148+
private final Function<Object, Optional<Object>> idCollector;
149+
150+
private DatabaseImpl(T entity,
151+
Function<Object, Optional<Object>> idCollector) {
152+
add(entity);
153+
this.entity = entity;
154+
this.idCollector = idCollector;
155+
}
156+
157+
@SuppressWarnings("unchecked")
158+
private <E> void add(E entity) {
159+
Class<E> cls = (Class<E>) entity.getClass();
160+
if (!objects.containsKey(cls)) {
161+
objects.put(cls, new LinkedHashSet<>());
162+
}
163+
Set<E> set = (Set<E>) objects.get(cls);
164+
set.add(entity);
165+
}
166+
167+
@Override
168+
public T getObject() {
169+
return checkNotNull(entity, "20180504:160340");
170+
}
171+
172+
@Nullable
173+
@Override
174+
public <E> E find(Class<?> cls, Object id) {
175+
if (objects.containsKey(cls)) {
176+
@SuppressWarnings("unchecked")
177+
Set<E> set = (Set<E>) objects.get(cls);
178+
for (E e : set) {
179+
Optional<Object> eId = idCollector.apply(e);
180+
if (eId.isPresent() && eId.get().equals(id)) {
181+
return e;
182+
}
183+
}
184+
}
185+
return null;
186+
}
23187
}
24188
}
Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package pl.wavesoftware.test.entity;
22

3-
import lombok.AccessLevel;
43
import lombok.Getter;
54
import lombok.NoArgsConstructor;
65
import lombok.Setter;
@@ -9,9 +8,9 @@
98
* @author <a href="mailto:krzysztof.suszynski@wavesoftware.pl">Krzysztof Suszynski</a>
109
* @since 04.05.18
1110
*/
11+
@Setter
12+
@Getter
1213
@NoArgsConstructor
1314
public abstract class AbstractEntity {
14-
@Setter(AccessLevel.PROTECTED)
15-
@Getter
1615
private Object reference;
1716
}

src/test/java/pl/wavesoftware/test/entity/Pet.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,6 @@ public class Pet extends AbstractEntity {
1717
private String name;
1818
@Nullable
1919
private Owner owner;
20+
@Nullable
21+
private Toy toy;
2022
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package pl.wavesoftware.test.entity;
2+
3+
import lombok.AllArgsConstructor;
4+
import lombok.Getter;
5+
import lombok.NoArgsConstructor;
6+
import lombok.Setter;
7+
8+
/**
9+
* @author <a href="mailto:krzysztof.suszynski@wavesoftware.pl">Krzysztof Suszynski</a>
10+
* @since 04.05.18
11+
*/
12+
@Setter
13+
@Getter
14+
@AllArgsConstructor
15+
@NoArgsConstructor
16+
public class Toy extends AbstractEntity {
17+
private String name;
18+
}

0 commit comments

Comments
 (0)