/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.xenei.junit.contract; import static org.junit.Assert.*; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import org.junit.Test; import org.junit.runner.Description; import org.junit.runner.notification.Failure; import org.junit.runner.notification.RunNotifier; import org.junit.runners.model.RunnerBuilder; import org.mockito.ArgumentCaptor; import org.xenei.junit.bad.BadAbstract; import org.xenei.junit.bad.BadNoInject; /** * Test ContractSuite * */ public class ContractSuiteTest { /** * Test that @Contract annotated classes may not be abstract. * * @throws Throwable * on error */ @Test public void testBadAbstract() throws Throwable { final RunnerBuilder builder = mock(RunnerBuilder.class); final ContractSuite cs = new ContractSuite(BadAbstractTest.class, builder); final RunNotifier notifier = mock(RunNotifier.class); cs.run(notifier); final ArgumentCaptor<Description> description = ArgumentCaptor .forClass(Description.class); verify(notifier).fireTestStarted(description.capture()); assertEquals(BadAbstractTest.class.getName(), description.getValue() .getClassName()); final ArgumentCaptor<Failure> failure = ArgumentCaptor .forClass(Failure.class); verify(notifier).fireTestFailure(failure.capture()); final Throwable throwable = failure.getValue().getException(); assertTrue("Should be illegal state exception", throwable instanceof IllegalStateException); assertEquals( "Classes annotated with @Contract (class org.xenei.junit.bad.BadAbstract) must not be abstract", throwable.getMessage()); verify(notifier).fireTestFinished(description.capture()); assertEquals(BadAbstractTest.class.getName(), description.getValue() .getClassName()); } /** * Test that @Contract classes must have a @Contract.Inject annotation on a * public non-abstract declared setter method. * * @throws Throwable * on error. */ @Test public void testBadNoInject() throws Throwable { final RunnerBuilder builder = mock(RunnerBuilder.class); final ContractSuite cs = new ContractSuite(BadNoInjectTest.class, builder); final RunNotifier notifier = mock(RunNotifier.class); cs.run(notifier); final ArgumentCaptor<Description> description = ArgumentCaptor .forClass(Description.class); verify(notifier).fireTestStarted(description.capture()); if (BadNoInject.class.getName().equals( description.getValue().getClassName())) { final ArgumentCaptor<Failure> failure = ArgumentCaptor .forClass(Failure.class); verify(notifier).fireTestFailure(failure.capture()); final Throwable throwable = failure.getValue().getException(); assertTrue("Should be illegal state exception", throwable instanceof IllegalStateException); assertEquals( "Classes annotated with @Contract (class org.xenei.junit.bad.BadNoInject) must include a @Contract.Inject annotation on a public non-abstract declared setter method", throwable.getMessage()); verify(notifier).fireTestFinished(description.capture()); assertEquals(BadNoInject.class.getName(), description.getValue() .getClassName()); } else if (BadNoInjectTest.class.getName().equals( description.getValue().getClassName())) { verify(notifier).fireTestFinished(description.capture()); assertEquals(BadNoInjectTest.class.getName(), description .getValue().getClassName()); } else { fail("Unexpected description class name: " + description.getValue().getClassName()); } } /** * A contract implementation for BadNoInject class. * */ @ContractImpl(value = BadNoInject.class) public static class BadNoInjectTest { // the producer to use for all the tests private final IProducer<BadNoInject> producer = new IProducer<BadNoInject>() { @Override public BadNoInject newInstance() { return new BadNoInject(); } @Override public void cleanUp() { } }; /** * The method to inject the producer into the test classes. * * @return the BadNoInject implementation. */ @Contract.Inject public IProducer<BadNoInject> getProducer() { return producer; } /** * A contract test to meet the test requirements. */ @ContractTest public void forceTest() { // just a test to meet the requirements. } } /** * A Contract test for the BadAbstract class */ @ContractImpl(value = BadAbstract.class) public static class BadAbstractTest { // the producer to use for all the tests private final IProducer<BadAbstract> producer = new IProducer<BadAbstract>() { @Override public BadAbstract newInstance() { return new BadAbstract() { }; } @Override public void cleanUp() { } }; /** * The method to inject the producer into the test classes. * * @return The BadAbstract class to inject. */ @Contract.Inject public IProducer<BadAbstract> getProducer() { return producer; } } }