Skip to content

Commit

Permalink
Merge pull request #413 from metafacture/339-metamorphVerifyNoMoreInt…
Browse files Browse the repository at this point in the history
…eractionsPart2

Metamorph tests verify that no unexpected interactions occurred (second and final batch).
  • Loading branch information
blackwinter authored Nov 9, 2021
2 parents 3a5e499 + def3c60 commit 49408cb
Show file tree
Hide file tree
Showing 27 changed files with 3,612 additions and 3,718 deletions.
156 changes: 73 additions & 83 deletions metamorph/src/test/java/org/metafacture/metamorph/MetamorphTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,25 +19,24 @@

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;

import java.util.HashMap;
import java.util.Map;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.metafacture.framework.helpers.DefaultStreamReceiver;
import org.metafacture.metamorph.api.Maps;
import org.metafacture.metamorph.api.NamedValueReceiver;
import org.mockito.ArgumentMatchers;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.exceptions.base.MockitoAssertionError;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;

import java.util.HashMap;
import java.util.Map;
import java.util.function.Consumer;

/**
* Tests for class {@link Metamorph}.
*
Expand All @@ -50,7 +49,7 @@ public final class MetamorphTest {
public MockitoRule mockitoRule = MockitoJUnit.rule();

@Mock
private NamedValueReceiver namedValueReceiver;
private NamedValueReceiver receiver;

private Metamorph metamorph;

Expand All @@ -62,81 +61,64 @@ public void createSystemUnderTest() {

@Test
public void shouldMapMatchingPath() {
setupSimpleMappingMorph();

metamorph.startRecord("");
metamorph.literal("testEntity.testLiteral", "testValue");

verify(namedValueReceiver).receive(eq("outName"), eq("testValue"),
any(), anyInt(), anyInt());
assertNamedValue(true, i -> {
i.literal("testEntity.testLiteral", "testValue");
});
}

@Test
public void shouldNotMapNonMatchingPath() {
setupSimpleMappingMorph();

metamorph.startRecord("");
metamorph.literal("nonMatching.path", "testValue");

verify(namedValueReceiver, never()).receive(any(), any(), any(), anyInt(),
anyInt());
assertNamedValue(false, i -> {
i.literal("nonMatching.path", "testValue");
});
}

@Test
public void shouldMapMatchingLiteralInMatchingEntity() {
setupSimpleMappingMorph();

metamorph.startRecord("");
metamorph.startEntity("testEntity");
metamorph.literal("testLiteral", "testValue");

verify(namedValueReceiver).receive(eq("outName"), eq("testValue"),
any(), anyInt(), anyInt());
assertNamedValue(true, i -> {
i.startEntity("testEntity");
i.literal("testLiteral", "testValue");
});
}

@Test
public void shouldNotMapNonMatchingLiteralInMatchingEntity() {
setupSimpleMappingMorph();

metamorph.startRecord("");
metamorph.startEntity("testEntity");
metamorph.literal("nonMatching", "testValue");

verify(namedValueReceiver, never()).receive(any(), any(), any(), anyInt(),
anyInt());
assertNamedValue(false, i -> {
i.startEntity("testEntity");
i.literal("nonMatching", "testValue");
});
}

@Test
public void shouldNotMapMatchingLiteralInNonMatchingEntity() {
setupSimpleMappingMorph();

metamorph.startRecord("");
metamorph.startEntity("nonMatching");
metamorph.literal("testLiteral", "testValue");

verify(namedValueReceiver, never()).receive(any(), any(), any(), anyInt(),
anyInt());
assertNamedValue(false, i -> {
i.startEntity("nonMatching");
i.literal("testLiteral", "testValue");
});
}
@Test
public void shouldNotMapLiteralWithoutMatchingEntity() {
setupSimpleMappingMorph();

metamorph.startRecord("");
metamorph.literal("testLiteral", "testValue");

verify(namedValueReceiver, never()).receive(any(), any(), any(), anyInt(),
anyInt());
assertNamedValue(false, i -> {
i.literal("testLiteral", "testValue");
});
}

/**
* Creates the Metamorph structure that corresponds to the Metamorph XML
* statement {@code <data source="testEntity.testLiteral" name="outName" />}.
*/
private void setupSimpleMappingMorph() {
final Data data = new Data();
data.setName("outName");
data.setNamedValueReceiver(namedValueReceiver);
metamorph.registerNamedValueReceiver("testEntity" + '.' + "testLiteral", data);
@Test
public void shouldFedbackLiteralsStartingWithAtIntoMetamorph() {
assertNamedValue(true, i -> {
final Data data1;
data1 = new Data();
data1.setName("@feedback");
i.addNamedValueSource(data1);
i.registerNamedValueReceiver("testLiteral", data1);

final Data data2 = new Data();
data2.setName("outName");
data2.setNamedValueReceiver(receiver);
i.registerNamedValueReceiver("@feedback", data2);

i.literal("testLiteral", "testValue");
});
}

@Test
Expand All @@ -160,26 +142,6 @@ public void shouldReturnDefaultValueIfMapIsKnownButNameIsUnknown() {
assertEquals("defaultValue", metamorph.getValue("testMap", "nameNotInMap"));
}

@Test
public void shouldFedbackLiteralsStartingWithAtIntoMetamorph() {
final Data data1;
data1 = new Data();
data1.setName("@feedback");
metamorph.addNamedValueSource(data1);
metamorph.registerNamedValueReceiver("testLiteral", data1);

final Data data2 = new Data();
data2.setName("outName");
data2.setNamedValueReceiver(namedValueReceiver);
metamorph.registerNamedValueReceiver("@feedback", data2);

metamorph.startRecord("");
metamorph.literal("testLiteral", "testValue");

verify(namedValueReceiver).receive(eq("outName"), eq("testValue"),
any(), anyInt(), anyInt());
}

@Test(expected=IllegalStateException.class)
public void shouldThrowIllegalStateExceptionIfEntityIsNotClosed() {
metamorph.startRecord("");
Expand All @@ -189,4 +151,32 @@ public void shouldThrowIllegalStateExceptionIfEntityIsNotClosed() {
metamorph.endRecord(); // Exception expected
}

private void assertNamedValue(final boolean matching, final Consumer<Metamorph> in) {
/**
* Creates the Metamorph structure that corresponds to the Metamorph XML
* statement {@code <data source="testEntity.testLiteral" name="outName" />}.
*/
final Data data = new Data();
data.setName("outName");
data.setNamedValueReceiver(receiver);
metamorph.registerNamedValueReceiver("testEntity" + '.' + "testLiteral", data);

metamorph.startRecord("");
in.accept(metamorph);

try {
if (matching) {
Mockito.verify(receiver).receive(
ArgumentMatchers.eq("outName"), ArgumentMatchers.eq("testValue"),
ArgumentMatchers.any(), ArgumentMatchers.eq(1), ArgumentMatchers.anyInt());
}

Mockito.verifyNoMoreInteractions(receiver);
}
catch (final MockitoAssertionError e) {
System.out.println(Mockito.mockingDetails(receiver).printInvocations());
throw e;
}
}

}
130 changes: 83 additions & 47 deletions metamorph/src/test/java/org/metafacture/metamorph/SplitterTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,19 @@

package org.metafacture.metamorph;

import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.metafacture.framework.StreamReceiver;
import org.mockito.InOrder;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.Mockito;
import org.mockito.exceptions.base.MockitoAssertionError;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;

import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Supplier;

/**
* Tests for class {@link Splitter}.
Expand All @@ -36,68 +39,101 @@
*/
public final class SplitterTest {

@Rule
public MockitoRule mockito = MockitoJUnit.rule();

@Mock
private StreamReceiver receiver1;

@Mock
private StreamReceiver receiver2;

private Splitter splitter;

@Before
public void setup() {
MockitoAnnotations.initMocks(this);
splitter = new Splitter("org/metafacture/metamorph/splitter-test.xml");
splitter.setReceiver("receiver-1", receiver1);
splitter.setReceiver("receiver-2", receiver2);
}

@Test
public void shouldPassRecordToReceiverWithMatchingKey() {
splitter.startRecord("1");
splitter.startEntity("data");
splitter.literal("forward-to", "receiver-1");
splitter.endEntity();
splitter.endRecord();
splitter.startRecord("2");
splitter.literal("forward-to", "receiver-2");
splitter.endRecord();

final InOrder ordered = inOrder(receiver1, receiver2);
ordered.verify(receiver1).startRecord("1");
ordered.verify(receiver1).startEntity("data");
ordered.verify(receiver1).literal("forward-to", "receiver-1");
ordered.verify(receiver1).endEntity();
ordered.verify(receiver1).endRecord();
ordered.verify(receiver2).startRecord("2");
ordered.verify(receiver2).literal("forward-to", "receiver-2");
ordered.verify(receiver2).endRecord();
ordered.verifyNoMoreInteractions();
assertSplitter(
i -> {
i.startRecord("1");
i.startEntity("data");
i.literal("forward-to", "receiver-1");
i.endEntity();
i.endRecord();
i.startRecord("2");
i.literal("forward-to", "receiver-2");
i.endRecord();
},
(o1, o2) -> {
o1.get().startRecord("1");
o1.get().startEntity("data");
o1.get().literal("forward-to", "receiver-1");
o1.get().endEntity();
o1.get().endRecord();
o2.get().startRecord("2");
o2.get().literal("forward-to", "receiver-2");
o2.get().endRecord();
}
);
}

@Test
public void shouldDiscardNonMatchingRecords() {
splitter.startRecord("1");
splitter.literal("forward-to", "none");
splitter.endRecord();

verifyZeroInteractions(receiver1, receiver2);
assertSplitter(
i -> {
i.startRecord("1");
i.literal("forward-to", "none");
i.endRecord();
},
(o1, o2) -> {
}
);
}

@Test
public void shouldPassResetStreamToAllReceivers() {
splitter.resetStream();

verify(receiver1).resetStream();
verify(receiver2).resetStream();
assertSplitter(
i -> {
i.resetStream();
},
(o1, o2) -> {
o1.get().resetStream();
o2.get().resetStream();
}
);
}

@Test
public void shouldPassCloseStreamToAllReceivers() {
splitter.closeStream();
assertSplitter(
i -> {
i.closeStream();
},
(o1, o2) -> {
o1.get().closeStream();
o2.get().closeStream();
}
);
}

private void assertSplitter(final Consumer<Splitter> in, final BiConsumer<Supplier<StreamReceiver>, Supplier<StreamReceiver>> out) {
final InOrder ordered = Mockito.inOrder(receiver1, receiver2);

final Splitter splitter = new Splitter("org/metafacture/metamorph/splitter-test.xml");
splitter.setReceiver("receiver-1", receiver1);
splitter.setReceiver("receiver-2", receiver2);

in.accept(splitter);

try {
out.accept(() -> ordered.verify(receiver1), () -> ordered.verify(receiver2));

verify(receiver1).closeStream();
verify(receiver2).closeStream();
ordered.verifyNoMoreInteractions();
Mockito.verifyNoMoreInteractions(receiver1);
Mockito.verifyNoMoreInteractions(receiver2);
}
catch (final MockitoAssertionError e) {
System.out.println(Mockito.mockingDetails(receiver1).printInvocations());
System.out.println(Mockito.mockingDetails(receiver2).printInvocations());
throw e;
}
}

}
Loading

0 comments on commit 49408cb

Please sign in to comment.