public InteractionRunner(final TestClass testClass, final Pact<? extends Interaction> pact, final PactSource pactSource) throws InitializationError { this.testClass = testClass; this.pact = pact; this.pactSource = pactSource; validate(); }
@Override protected Object runReflectiveCall() throws Throwable { return createTest(); } }.run();
protected AssertionError getAssertionError(final Map<String, Object> mismatches) { return new AssertionError(JUnitProviderTestSupport.generateErrorStringFromMismatches(mismatches)); }
@RunWith(PactRunner.class) @Provider("userservice") @PactFolder("../pact-message-consumer/target/pacts") public class UserCreatedMessageProviderTest { @TestTarget public final Target target = new CustomAmqpTarget(Collections.singletonList("io.reflectoring"));
protected void validate() throws InitializationError { final List<Throwable> errors = new ArrayList<>(); validatePublicVoidNoArgMethods(Before.class, false, errors); validatePublicVoidNoArgMethods(After.class, false, errors); validateStateChangeMethods(testClass, errors); validateConstructor(errors); validateTestTarget(errors); validateRules(errors); validateTargetRequestFilters(errors); if (!errors.isEmpty()) { throw new InitializationError(errors); } }
return createTest(); }.run(); } catch (Throwable e) { return new Fail(e); final Target target = lookupTarget(testInstance); statement = withStateChanges(interaction, testInstance, statement); statement = withBefores(interaction, testInstance, statement); statement = withRules(interaction, testInstance, statement); statement = withAfters(interaction, testInstance, statement); return statement;
@State("data count == 0") public void dataCountZero() { DataStore.INSTANCE.setDataCount(0); } }
@Override public void evaluate() throws Throwable { setupTargetForInteraction(target); target.addResultCallback((result, verifier) -> results.put(interaction, new Pair<>(result, verifier))); surrogateTestMethod(); target.testInteraction(pact.getConsumer().getName(), interaction, source); } };
protected Statement withStateChanges(final Interaction interaction, final Object target, final Statement prevStatement) { if (!interaction.getProviderStates().isEmpty()) { Statement stateChange = prevStatement; for (ProviderState state: interaction.getProviderStates()) { List<Pair<FrameworkMethod, State>> methods = getAnnotatedMethods(testClass, State.class) .stream() .map(method -> { final State annotation = method.getAnnotation(State.class); return new Pair<>(method, annotation); }) .filter(method -> ArrayUtils.contains(method.getSecond().value(), state.getName())) .collect(Collectors.toList()); if (methods.isEmpty()) { return new Fail(new MissingStateChangeMethod("MissingStateChangeMethod: Did not find a test class method annotated with @State(\"" + state.getName() + "\")")); } else { stateChange = new RunStateChanges(stateChange, methods, target, state); } } return stateChange; } else { return prevStatement; } }
protected Statement withRules(final Interaction interaction, final Object target, final Statement statement) { final List<TestRule> testRules = testClass.getAnnotatedMethodValues(target, Rule.class, TestRule.class); testRules.addAll(testClass.getAnnotatedFieldValues(target, Rule.class, TestRule.class)); return testRules.isEmpty() ? statement : new RunRules(statement, testRules, describeChild(interaction)); } }
@Override public void evaluate() throws Throwable { invokeStateChangeMethods(StateChangeAction.SETUP); next.evaluate(); invokeStateChangeMethods(StateChangeAction.TEARDOWN); }
public void reportVerificationResults(Boolean allPassed) { ProviderVerifierKt.reportVerificationResults(pact, allPassed, providerVersion()); }
private static List<FrameworkMethod> getAnnotatedMethods(TestClass testClass, Class<? extends Annotation> annotation){ List<FrameworkMethod> methodsFromTestClass = testClass.getAnnotatedMethods(annotation); List<FrameworkMethod> allMethods = new ArrayList<>(); allMethods.addAll(methodsFromTestClass); allMethods.addAll(getAnnotatedMethodsFromInterfaces(testClass, annotation)); return allMethods; }
protected void validateConstructor(final List<Throwable> errors) { if (!hasOneConstructor()) { errors.add(new Exception("Test class should have exactly one public constructor")); } if (!testClass.isANonStaticInnerClass() && hasOneConstructor() && (testClass.getOnlyConstructor().getParameterTypes().length != 0)) { errors.add(new Exception("Test class should have exactly one public zero-argument constructor")); } }
private static void validateStateChangeMethods(TestClass testClass, final List<Throwable> errors) { getAnnotatedMethods(testClass, State.class).forEach(method -> { method.validatePublicVoid(false, errors); if (method.getMethod().getParameterCount() == 1 && !Map.class.isAssignableFrom(method.getMethod().getParameterTypes()[0])) { errors.add(new Exception("Method " + method.getName() + " should take only a single Map parameter")); } else if (method.getMethod().getParameterCount() > 1) { errors.add(new Exception("Method " + method.getName() + " should either take no parameters or a single Map parameter")); } }); }
private void invokeStateChangeMethods(StateChangeAction action) throws Throwable { for (Pair<FrameworkMethod, State> pair : methods) { if (pair.getSecond().action() == action) { if (pair.getFirst().getMethod().getParameterCount() == 1) { pair.getFirst().invokeExplosively(target, providerState.getParams()); } else { pair.getFirst().invokeExplosively(target); } } } } }
@State("data count > 0") public void dataCountGreaterThanZero() { DataStore.INSTANCE.setDataCount(1000); }
@Override public Description getDescription() { final Description description = Description.createSuiteDescription(testClass.getJavaClass()); for (Interaction i: pact.getInteractions()) { description.addChild(describeChild(i)); } return description; }
@State("person data") // same as the "given()" part in our consumer test public void personData() { Person peterPan = new Person("Peter", "Pan"); when(personRepository.findByLastName("Pan")).thenReturn(Optional.of (peterPan)); } }
@State({"provider accepts a new person", "person 42 exists"}) public void toCreatePersonState() { User user = new User(); user.setId(42L); user.setFirstName("Arthur"); user.setLastName("Dent"); when(userRepository.findById(eq(42L))).thenReturn(Optional.of(user)); when(userRepository.save(any(User.class))).thenReturn(user); }