Commits

Dariusz Kordonski  committed 7cbda2d

initial version

  • Participants

Comments (0)

Files changed (28)

+(test'file)
+*.backup
+*.iml
+*.ipr
+*.iws
+*.log
+*10018__*
+*10019_a*
+.DS_Store
+.classpath
+.clover/
+.idea
+.project
+.settings
+.*.swp
+/classes/
+BuildUtils.java
+DummyAttachment
+atlassian-bundled-plugins.zip
+atlassian-jira-*-standalone
+check-cache.xml
+enterprise-with-flush.xml
+enterprise.xml
+filename?
+jira-components/jira-core/dependencies.txt.tmp
+jira-components/jira-tests/filename.xml
+jira-components/jira-tests/filename.zip
+jira-home
+jira.idea.properties
+localtest.properties
+modules
+outputtest.xml
+professional-with-flush.xml
+professional.xml
+release.info
+rest-fields.xml
+svn.info.xml
+target/
+tomcat
+tomcat4
+tomcat6
+tomcatBase/
+/jirahome
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>com.atlassian.pom</groupId>
+        <artifactId>atlassian-private-pom</artifactId>
+        <version>25.9</version>
+    </parent>
+
+    <groupId>com.atlassian</groupId>
+    <artifactId>unittests-tutorial</artifactId>
+    <version>1.0-SNAPSHOT</version>
+    <packaging>jar</packaging>
+    <name>Unit tests with JUnit4, Mockito and Hamcrest - Tutorial</name>
+    <description>Code assisting the unit tests tutorial</description>
+
+    <!--<scm>-->
+    <!--<connection>scm:git:ssh://git@bitbucket.org/atlassian/atlassian-selenium.git</connection>-->
+    <!--<developerConnection>scm:git:ssh://git@bitbucket.org/atlassian/atlassian-selenium.git</developerConnection>-->
+    <!--<url>https://bitbucket.org/atlassian/atlassian-selenium/</url>-->
+    <!--</scm>-->
+
+    <properties>
+        <jdkLevel>1.6</jdkLevel>
+        <hamcrest.version>1.2</hamcrest.version>
+        <junit.version>4.11</junit.version>
+        <mockito.version>1.9.5</mockito.version>
+    </properties>
+
+
+    <dependencies>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit-dep</artifactId>
+            <version>${junit.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-core</artifactId>
+            <version>${mockito.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.hamcrest</groupId>
+            <artifactId>hamcrest-core</artifactId>
+            <version>${hamcrest.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.hamcrest</groupId>
+            <artifactId>hamcrest-library</artifactId>
+            <version>${hamcrest.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+            <version>12.0</version>
+            <scope>test</scope>
+        </dependency>
+
+    </dependencies>
+
+    <build>
+        <plugins>
+            <!--<plugin>-->
+                <!--<groupId>org.apache.maven.plugins</groupId>-->
+                <!--<artifactId>maven-enforcer-plugin</artifactId>-->
+                <!--<version>1.0.1</version>-->
+                <!--<executions>-->
+                    <!--<execution>-->
+                        <!--<id>ban_conflicting_dependencies</id>-->
+                        <!--<goals>-->
+                            <!--<goal>enforce</goal>-->
+                        <!--</goals>-->
+                        <!--<phase>validate</phase>-->
+                        <!--<configuration>-->
+                            <!--<rules>-->
+                                <!--<bannedDependencies>-->
+                                    <!--<searchTransitive>true</searchTransitive>-->
+                                    <!--<message>make sure junit, hamcrest-all and mockito-all are not accidentally included as transitive dependency. Use junit-dep, hamcrest-core, hamcrest-library or mockito-core instead</message>-->
+                                    <!--<excludes>-->
+                                        <!--<exclude>junit:junit</exclude>-->
+                                        <!--<exclude>org.mockito:mockito-all</exclude>-->
+                                        <!--<exclude>org.hamcrest:hamcrest-all</exclude>-->
+                                    <!--</excludes>-->
+                                <!--</bannedDependencies>-->
+                            <!--</rules>-->
+                            <!--<fail>true</fail>-->
+                        <!--</configuration>-->
+                    <!--</execution>-->
+                <!--</executions>-->
+            <!--</plugin>-->
+        </plugins>
+    </build>
+</project>

File src/test/java/com/atlassian/example/ExampleTest.java

+package com.atlassian.example;
+
+
+import org.junit.Test;
+
+public class ExampleTest {
+
+    @Test
+    public void iWillFailInAnOldWay(){
+        junit.framework.Assert.fail();
+    }
+
+
+    @Test
+    public void iWillFailInANewWay(){
+        org.junit.Assert.fail();
+    }
+
+    @Test
+    public void iWillFailByThrowingUp(){
+        throw new ThrowingUp();
+    }
+
+    public static class ThrowingUp extends RuntimeException
+    {
+    }
+
+}

File src/test/java/com/atlassian/example/TestThatChainRules.java

+package com.atlassian.example;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.RuleChain;
+import org.junit.rules.TestRule;
+import org.junit.rules.TestWatcher;
+import org.junit.runner.Description;
+
+public class TestThatChainRules {
+
+    public static class RuleOne extends TestWatcher {
+
+        @Override
+        protected void starting(Description description) {
+            System.out.println("One Started");
+        }
+
+        @Override
+        protected void finished(Description description) {
+            System.out.println("One Finished");
+        }
+    }
+
+    public static class RuleTwo extends TestWatcher {
+
+        @Override
+        protected void starting(Description description) {
+            System.out.println("Two Started");
+        }
+
+        @Override
+        protected void finished(Description description) {
+            System.out.println("Two Finished");
+        }
+    }
+
+    @Rule public final TestRule theChain = RuleChain.emptyRuleChain()
+            .around(new RuleOne()) // outer
+            .around(new RuleTwo()); // inner
+
+
+    @Test
+    public void iWillPrintSomeRubbish() {
+    }
+
+}

File src/test/java/com/atlassian/example/TestThatRuleMustBeDeclaredAsRule.java

+package com.atlassian.example;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+
+public class TestThatRuleMustBeDeclaredAsRule {
+
+
+    @Rule public final Object rule = new TemporaryFolder();
+
+    @Test
+    public void someTest() {
+    }
+}

File src/test/java/com/atlassian/example/TestThatRules.java

+package com.atlassian.example;
+
+import com.atlassian.example.matchers.ErrorMatchers;
+import org.hamcrest.Description;
+import org.hamcrest.Matcher;
+import org.hamcrest.TypeSafeDiagnosingMatcher;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.junit.rules.TemporaryFolder;
+
+import java.io.IOException;
+
+import static com.atlassian.example.matchers.ErrorMatchers.specificError;
+import static org.junit.Assert.assertTrue;
+
+public class TestThatRules {
+
+
+    @Rule public final TemporaryFolder folder = new TemporaryFolder();
+    @Rule public final ExpectedException exception = ExpectedException.none();
+
+
+    @Test
+    public void iNeedFileSystemAccessAmIReallyAUnitTestAnyway() throws IOException {
+        assertTrue(folder.newFile().isFile());
+    }
+
+    @Test
+    public void iWillThrowException() {
+        exception.expect(IllegalStateException.class);
+        exception.expectMessage("failing miserably");
+        throw new IllegalStateException("I am failing miserably");
+    }
+
+    @Test
+    public void iWillThrowAnotherExceptionThatWillBeMatchedByAMatcher() {
+        exception.expect(specificError(BaseException.class, withErrorCode("007")));
+        throw new BaseException("007");
+    }
+
+
+    public static class BaseException extends RuntimeException {
+
+        private final String errorCode;
+
+        public BaseException(String errorCode) {
+            this.errorCode = errorCode;
+        }
+    }
+
+    public static Matcher<BaseException> withErrorCode(final String expectedCode) {
+
+        return new TypeSafeDiagnosingMatcher<BaseException>() {
+
+            @Override
+            protected boolean matchesSafely(BaseException e, Description description) {
+                return e.errorCode.equals(expectedCode);
+            }
+
+            @Override
+            public void describeTo(Description description) {
+                description.appendText("BaseException with error code ").appendValue(expectedCode);
+            }
+        };
+    }
+
+}

File src/test/java/com/atlassian/example/TestWithRandomRuleOrder.java

+package com.atlassian.example;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.RuleChain;
+import org.junit.rules.TestRule;
+import org.junit.rules.TestWatcher;
+import org.junit.runner.Description;
+
+import java.util.Arrays;
+
+public class TestWithRandomRuleOrder {
+
+    public static class RuleOne extends TestWatcher {
+
+        @Override
+        protected void starting(Description description) {
+            System.out.println("One Started");
+        }
+
+        @Override
+        protected void finished(Description description) {
+            System.out.println("One Finished");
+        }
+    }
+
+    public static class RuleTwo extends TestWatcher {
+
+        @Override
+        protected void starting(Description description) {
+            System.out.println("Two Started");
+        }
+
+        @Override
+        protected void finished(Description description) {
+            System.out.println("Two Finished");
+        }
+    }
+
+    @Rule public final TestRule one = new RuleOne();
+    @Rule public final TestRule two = new RuleTwo();
+
+
+    @Test
+    public void iWillPrintSomeRubbish() {
+    }
+
+}

File src/test/java/com/atlassian/example/ignorewithrule/IgnoreInUnexpectedOs.java

+package com.atlassian.example.ignorewithrule;
+
+import org.junit.Assume;
+import org.junit.rules.TestRule;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+
+import java.util.Arrays;
+import java.util.EnumSet;
+
+public class IgnoreInUnexpectedOs implements TestRule {
+
+
+    @Override
+    public Statement apply(Statement base, final Description description) {
+        return new Statement() {
+            @Override
+            public void evaluate() throws Throwable {
+                EnumSet ignoredTypes = getIgnored(description);
+                Assume.assumeFalse("This test should be ignored for OS " + OsType.current(), isRunningAnyOf(ignoredTypes));
+            }
+        };
+    }
+
+    public EnumSet<OsType> getIgnored(Description description) {
+        IgnoreOs ignoreOs = description.getAnnotation(IgnoreOs.class);
+        return ignoreOs != null && ignoreOs.value().length > 0 ? EnumSet.copyOf(Arrays.asList(ignoreOs.value())) : EnumSet.noneOf(OsType.class);
+    }
+
+    private boolean isRunningAnyOf(EnumSet ignoredTypes) {
+        return ignoredTypes.contains(OsType.current());
+    }
+}

File src/test/java/com/atlassian/example/ignorewithrule/IgnoreOs.java

+package com.atlassian.example.ignorewithrule;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+public @interface IgnoreOs {
+
+    OsType[] value() default OsType.WIN;
+}

File src/test/java/com/atlassian/example/ignorewithrule/OsType.java

+package com.atlassian.example.ignorewithrule;
+
+public enum OsType {
+
+    MAC("mac"),
+    WIN("win"),
+    UNIX("nix"),
+    LINUX("nux");
+
+    private static String os = System.getProperty("os.name").toLowerCase();
+
+    public static OsType current() {
+        for (OsType osType : values()) {
+            if (osType.isRunning()) {
+                return osType;
+            }
+        }
+        throw new IllegalStateException("Unknown OS: " + os);
+    }
+
+    private final String matchingString;
+
+    private OsType(String matchingString) {
+        this.matchingString = matchingString;
+    }
+
+    public boolean isRunning() {
+        return os.contains(matchingString);
+    }
+}

File src/test/java/com/atlassian/example/ignorewithrule/TestForMultipleOs.java

+package com.atlassian.example.ignorewithrule;
+
+import org.junit.Rule;
+import org.junit.Test;
+
+public class TestForMultipleOs {
+
+    @Rule public final IgnoreInUnexpectedOs ignoreOs = new IgnoreInUnexpectedOs();
+
+    @Test
+    @IgnoreOs(OsType.LINUX)
+    public void ignoreInLinux() {
+        System.out.println("This is not Linux!");
+    }
+
+    @Test
+    @IgnoreOs(OsType.WIN)
+    public void ignoreInWindows() {
+        System.out.println("This is not Windows! Thank God!");
+    }
+
+    @Test
+    @IgnoreOs(OsType.MAC)
+    public void ignoreInMac() {
+        System.out.println("This is not Mac! Thank God!");
+    }
+}

File src/test/java/com/atlassian/example/matchers/ErrorMatchers.java

+package com.atlassian.example.matchers;
+
+import org.hamcrest.Description;
+import org.hamcrest.Matcher;
+import org.hamcrest.TypeSafeMatcher;
+import org.junit.runners.model.InitializationError;
+
+import static org.hamcrest.Matchers.instanceOf;
+
+/**
+ * Matchers for Java errors.
+ *
+ */
+public final class ErrorMatchers
+{
+    private ErrorMatchers()
+    {
+        throw new AssertionError("Don't instantiate me");
+    }
+
+
+    // based off ExpectedException internals
+
+    public static Matcher<Throwable> withMessage(final String... expectedSubstrings)
+    {
+        return withMessage(LangMatchers.containsInOrder(expectedSubstrings));
+    }
+
+    public static Matcher<Throwable> withMessage(final Matcher<String> messageMatcher)
+    {
+        return new TypeSafeMatcher<Throwable>()
+        {
+            @Override
+            public boolean matchesSafely(Throwable throwable)
+            {
+                return messageMatcher.matches(throwable.getMessage());
+            }
+
+            @Override
+            public void describeTo(Description description)
+            {
+                description.appendText("a Throwable with message ").appendDescriptionOf(messageMatcher);
+            }
+        };
+    }
+
+    public static Matcher<Throwable> withCause(Class<? extends Throwable> causeType)
+    {
+        // can be fixed when moved to Hamcrest 1.2
+        return withCause(LangMatchers.isInstance(causeType));
+    }
+
+    public static Matcher<Throwable> withCause(final Matcher<? extends Throwable> causeMatcher)
+    {
+        return new TypeSafeMatcher<Throwable>()
+        {
+            @Override
+            public boolean matchesSafely(Throwable throwable)
+            {
+                return causeMatcher.matches(throwable.getCause());
+            }
+
+            @Override
+            public void describeTo(Description description)
+            {
+                description.appendText("a Throwable with cause (").appendDescriptionOf(causeMatcher).appendText(")");
+            }
+        };
+    }
+
+    public static <T extends Throwable> Matcher<Throwable> specificError(final Class<T> errorClass, final Matcher<T> specificMatcher)
+    {
+        return new TypeSafeMatcher<Throwable>()
+        {
+            @Override
+            public boolean matchesSafely(Throwable throwable)
+            {
+                return instanceOf(errorClass).matches(throwable) && specificMatcher.matches(errorClass.cast(throwable));
+            }
+
+            @Override
+            public void describeTo(Description description)
+            {
+                description.appendText("an instance of ").appendValue(errorClass)
+                        .appendText(" that is (").appendDescriptionOf(specificMatcher).appendText(")");
+            }
+        };
+    }
+
+    public static Matcher<InitializationError> withCauses(final Matcher<Iterable<Throwable>> causesMatcher)
+    {
+        return new TypeSafeMatcher<InitializationError>()
+        {
+            @Override
+            public boolean matchesSafely(InitializationError initializationError)
+            {
+                return causesMatcher.matches(initializationError.getCauses());
+            }
+
+            @Override
+            public void describeTo(Description description)
+            {
+                description.appendText("a JUnit InitializationError with causes ").appendDescriptionOf(causesMatcher);
+            }
+        };
+    }
+
+}

File src/test/java/com/atlassian/example/matchers/IterableMatchers.java

+package com.atlassian.example.matchers;
+
+import com.google.common.collect.Iterables;
+import org.hamcrest.Description;
+import org.hamcrest.Matcher;
+import org.hamcrest.Matchers;
+import org.hamcrest.TypeSafeDiagnosingMatcher;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
+/**
+ * Some moar iterable matchers.
+ *
+ */
+public final class IterableMatchers
+{
+
+    private IterableMatchers()
+    {
+        throw new AssertionError("Don't instantiate me");
+    }
+
+
+    public static <E> Matcher<Iterable<E>> emptyIterable(Class<E> elementType)
+    {
+        return Matchers.emptyIterable();
+    }
+
+    public static <E> Matcher<Iterable<E>> iterableWithSize(int expected, Class<E> elementType)
+    {
+        return Matchers.iterableWithSize(expected);
+    }
+
+    public static <E> Matcher<Iterable<E>> hasSizeOfAtLeast(final int expectedMinimumSize, Class<E> elementType)
+    {
+        return hasSizeOfAtLeast(expectedMinimumSize);
+    }
+
+    public static <E> Matcher<Iterable<E>> hasSizeOfAtLeast(final int expectedMinimumSize)
+    {
+        checkArgument(expectedMinimumSize >= 0, "Expected minimum size must be at least 0");
+        return new TypeSafeDiagnosingMatcher<Iterable<E>>()
+        {
+            @Override
+            protected boolean matchesSafely(Iterable<E> items, Description mismatchDescription)
+            {
+                final int size = Iterables.size(items);
+                if (size < expectedMinimumSize)
+                {
+                    mismatchDescription.appendText("Expected size of at least ").appendValue(expectedMinimumSize)
+                            .appendText(" but was only ").appendValue(size);
+                    return false;
+                }
+                else
+                {
+                    return true;
+                }
+            }
+
+            @Override
+            public void describeTo(Description description)
+            {
+                description.appendText("an iterable with size of at least ").appendValue(expectedMinimumSize)
+                        .appendText(" or more");
+            }
+        };
+    }
+
+    public static <E> Matcher<Iterable<E>> isSingleton(Class<E> type, E singleElement)
+    {
+        return isSingleton(singleElement);
+    }
+
+    public static <E> Matcher<Iterable<E>> isSingleton(E expectedElement)
+    {
+        return isSingleton((Matcher<E>)Matchers.is(expectedElement));
+    }
+
+    public static <E> Matcher<Iterable<E>> isSingleton(Matcher<E> singleElementMatcher)
+    {
+        return Matchers.allOf(Matchers.<E>iterableWithSize(1), hasItemThat(singleElementMatcher));
+    }
+
+    public static <E> Matcher<Iterable<E>> hasItems(Class<E> itemType, E... items)
+    {
+        return Matchers.hasItems(items);
+    }
+
+    public static <E> Matcher<Iterable<E>> hasItemsThat(Class<E> itemType, Matcher<E>... items)
+    {
+        return Matchers.hasItems(items);
+    }
+
+    public static <E> Matcher<Iterable<E>> hasItemThat(Matcher<E> itemMatcher)
+    {
+        return (Matcher)Matchers.hasItem(itemMatcher);
+    }
+
+    public static <E> Matcher<Iterable<E>> hasNoItemThat(Matcher<E> itemMatcher)
+    {
+        return Matchers.not(hasItemThat(itemMatcher));
+    }
+
+    public static <E> Matcher<Iterable<E>> containsAt(E item, int at)
+    {
+        return containsAt((Matcher<E>)Matchers.is(item), at);
+    }
+
+    public static <E> Matcher<Iterable<E>> containsFirst(E item)
+    {
+        return containsAt(item, 0);
+    }
+
+    public static <E> Matcher<Iterable<E>> containsFirst(Matcher<E> itemMatcher)
+    {
+        return containsAt(itemMatcher, 0);
+    }
+
+    public static <E> Matcher<Iterable<E>> containsLast(E item)
+    {
+        return containsLast((Matcher<E>)Matchers.is(item));
+    }
+
+    public static <E> Matcher<Iterable<E>> containsLast(final Matcher<E> itemMatcher)
+    {
+        return new TypeSafeDiagnosingMatcher<Iterable<E>>()
+        {
+            @Override
+            protected boolean matchesSafely(Iterable<E> items, Description mismatchDescription)
+            {
+                E lastItem = Iterables.getLast(items);
+                return itemMatcher.matches(lastItem);
+            }
+
+            @Override
+            public void describeTo(Description description)
+            {
+                description.appendText("an iterable containing an element at last position that matches ")
+                        .appendDescriptionOf(itemMatcher);
+            }
+        };
+    }
+
+    public static <E> Matcher<Iterable<E>> containsAt(final Matcher<E> itemMatcher, final int at)
+    {
+        checkArgument(at >= 0, "at must be at least 0");
+        return Matchers.allOf(IterableMatchers.<E>hasSizeOfAtLeast(at+1), new TypeSafeDiagnosingMatcher<Iterable<E>>()
+        {
+            @Override
+            protected boolean matchesSafely(Iterable<E> items, Description mismatchDescription)
+            {
+                E itemAt = Iterables.get(items, at);
+                return itemMatcher.matches(itemAt);
+            }
+
+            @Override
+            public void describeTo(Description description)
+            {
+                description.appendText("an iterable containing an element at position ").appendValue(at)
+                        .appendText(" that matches ").appendDescriptionOf(itemMatcher);
+            }
+        });
+    }
+
+
+    public static <E> Matcher<Iterable<E>> exactMatchInOrder(final Matcher<? super E>... elementMatchers) {
+        return Matchers.allOf(Matchers.<E>iterableWithSize(elementMatchers.length),
+                Matchers.contains(elementMatchers));
+    }
+}

File src/test/java/com/atlassian/example/matchers/LangMatchers.java

+package com.atlassian.example.matchers;
+
+import org.hamcrest.Description;
+import org.hamcrest.Matcher;
+import org.hamcrest.Matchers;
+import org.hamcrest.TypeSafeMatcher;
+
+/**
+ * More matchers for core Java thingies.
+ *
+ */
+public final class LangMatchers
+{
+
+    private LangMatchers()
+    {
+        throw new AssertionError("Don't instantiate me");
+    }
+
+    @SuppressWarnings("unchecked")
+    public static <T> Matcher<T> isInstance(Class<? extends T> type)
+    {
+        return (Matcher<T>) Matchers.instanceOf(type);
+    }
+
+    public static Matcher<String> containsInOrder(final CharSequence... substrings)
+    {
+        return new TypeSafeMatcher<String>()
+        {
+            @Override
+            public boolean matchesSafely(String item)
+            {
+                int index = -1;
+                for (CharSequence substring : substrings)
+                {
+                    index = item.indexOf(substring.toString(), index);
+                    if (index < 0)
+                    {
+                        return false;
+                    }
+                }
+                return true;
+            }
+
+            @Override
+            public void describeTo(Description description)
+            {
+                description.appendText("a string that contains (in order): ").appendValueList("(", ",", ")", substrings);
+            }
+        };
+    }
+}

File src/test/java/com/atlassian/example/matchers/Person.java

+package com.atlassian.example.matchers;
+
+public class Person {
+
+    private final String firstName;
+    private final String lastName;
+    private final String phone;
+    private final String email;
+
+    public Person(String name, String lastName, String phone, String email) {
+        this.firstName = name;
+        this.lastName = lastName;
+        this.phone = phone;
+        this.email = email;
+    }
+
+    public Person(String name, String lastName) {
+        this(name, lastName, null, null);
+    }
+
+
+    public String getFirstName() {
+        return firstName;
+    }
+
+    public String getLastName() {
+        return lastName;
+    }
+
+    public String getPhone() {
+        return phone;
+    }
+
+    public String getEmail() {
+        return email;
+    }
+}

File src/test/java/com/atlassian/example/matchers/PersonMatchers.java

+package com.atlassian.example.matchers;
+
+import org.hamcrest.Description;
+import org.hamcrest.Matcher;
+import org.hamcrest.TypeSafeDiagnosingMatcher;
+import org.hamcrest.TypeSafeMatcher;
+
+public final class PersonMatchers {
+
+    private PersonMatchers() {
+        throw new AssertionError("Don't instantiate me");
+    }
+
+    public static Matcher<Person> withName(final String firstName, final String lastName) {
+        return new TypeSafeMatcher<Person>() {
+
+            @Override
+            protected boolean matchesSafely(Person person) {
+                return (firstName.equals(person.getFirstName()) && lastName.equals(person.getLastName()));
+            }
+
+            @Override
+            public void describeTo(Description description) {
+                description.appendText("a Person with name ").appendValue(firstName).appendText(" ").appendValue(lastName);
+            }
+        };
+    }
+
+
+
+
+
+
+
+
+
+    public static Matcher<Person> withNameDiagnosing(final String firstName, final String lastName) {
+        return new TypeSafeDiagnosingMatcher<Person>() {
+
+            @Override
+            protected boolean matchesSafely(Person person, Description mismatch) {
+                boolean matching = true;
+                if (!firstName.equals(person.getFirstName())) {
+                    mismatch.appendText("Expected first name ").appendValue(firstName).appendText(" but was ")
+                            .appendValue(person.getFirstName());
+                    matching = false;
+                }
+                if (!lastName.equals(person.getLastName())) {
+                    mismatch.appendText("Expected last name ").appendValue(lastName).appendText(" but was ")
+                            .appendValue(person.getLastName());
+                    matching = false;
+                }
+                return matching;
+            }
+
+            @Override
+            public void describeTo(Description description) {
+                description.appendText("a Person with name ").appendValue(firstName).appendText(" ").appendValue(lastName);
+            }
+        };
+    }
+}

File src/test/java/com/atlassian/example/matchers/TestPersonStuff.java

+package com.atlassian.example.matchers;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
+import org.hamcrest.MatcherAssert;
+import org.hamcrest.Matchers;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class TestPersonStuff {
+
+
+    @Test
+    public void shouldContainExpectedPersonsTraditionalWay() {
+        Iterable<Person> actual = getPersonsFromSomewhere();
+        assertEquals(3, Iterables.size(actual));
+        assertEquals("Wojciech", Iterables.get(actual, 0).getFirstName());
+        assertEquals("Seliga", Iterables.get(actual, 0).getLastName());
+        // etc.
+    }
+
+    @Test
+    public void shouldContainExpectedPersonsUsingMatchers() {
+        // change to diagnostic for better error output
+        MatcherAssert.assertThat(getPersonsFromSomewhere(), IterableMatchers.exactMatchInOrder(
+                        PersonMatchers.withName("Wojciech", "Seliga"),
+                        PersonMatchers.withName("Adam", "Jakubowski"),
+                        PersonMatchers.withName("Michal", "Orzechowski")
+                ));
+    }
+
+    private Iterable<Person> getPersonsFromSomewhere() {
+        return ImmutableList.of(
+                new Person("Wojciech", "Seliga"),
+                new Person("Adam", "Jakubowski"),
+                new Person("Michal", "Orzechowski")
+        );
+    }
+}

File src/test/java/com/atlassian/example/mockito/ImportantService.java

+package com.atlassian.example.mockito;
+
+public interface ImportantService {
+
+    public String methodWithReturn();
+
+    public void voidMethod();
+
+    public String methodWithArgument(String arg);
+}

File src/test/java/com/atlassian/example/mockito/InitMockitoMocks.java

+package com.atlassian.example.mockito;
+
+import org.junit.rules.TestRule;
+import org.junit.rules.TestWatcher;
+import org.junit.runner.Description;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+
+public class InitMockitoMocks extends TestWatcher {
+
+    private final Object test;
+
+    public InitMockitoMocks(Object test) {
+        this.test = test;
+    }
+
+    @Override
+    protected void starting(Description description) {
+        MockitoAnnotations.initMocks(test);
+    }
+
+    @Override
+    protected void finished(Description description) {
+        Mockito.validateMockitoUsage();
+    }
+}

File src/test/java/com/atlassian/example/mockito/MockitoExamples.java

+package com.atlassian.example.mockito;
+
+import org.hamcrest.Matchers;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InOrder;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.runners.MockitoJUnitRunner;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+@RunWith(MockitoJUnitRunner.class)
+public class MockitoExamples {
+
+
+    @Mock private ImportantService service;
+
+
+    @Test
+    public void useMockitoDirectlyToCreateMock() {
+        final ImportantService mock = Mockito.mock(ImportantService.class);
+        assertNotNull(service);
+        assertNotNull(mock);
+    }
+
+    @Test
+    public void stubReturn() {
+        Mockito.when(service.methodWithReturn()).thenReturn("one").thenReturn("two");
+        assertEquals("one", service.methodWithReturn());
+        assertEquals("two", service.methodWithReturn());
+    }
+
+    @Test(expected = IllegalStateException.class)
+    public void stubReturnAndThrow() {
+        Mockito.when(service.methodWithReturn()).thenReturn("one", "two").thenThrow(new IllegalStateException("w000t"));
+        assertEquals("one", service.methodWithReturn());
+        assertEquals("two", service.methodWithReturn());
+        service.methodWithReturn();
+    }
+
+    @Test(expected = IllegalStateException.class)
+    public void stubVoidMethod() {
+        Mockito.doThrow(new IllegalStateException("w000t")).when(service).voidMethod();
+        service.voidMethod();
+    }
+
+    @Test
+    public void verifyInteractions() {
+        service.methodWithReturn();
+        service.voidMethod();
+        service.voidMethod();
+        Mockito.verify(service, Mockito.times(2)).voidMethod();
+        Mockito.verify(service).methodWithReturn();
+        Mockito.verifyNoMoreInteractions(service);
+    }
+
+    @Test
+    public void verifyInteractionsInOrder() {
+        service.methodWithReturn();
+        service.voidMethod();
+        service.voidMethod();
+        InOrder inOrder = Mockito.inOrder(service);
+        inOrder.verify(service).methodWithReturn();
+        inOrder.verify(service, Mockito.times(2)).voidMethod();
+    }
+
+    @Test
+    public void argumentMatchers() {
+        Mockito.when(service.methodWithArgument(Mockito.contains("w000t"))).thenReturn("yeah!");
+//        Mockito.when(service.methodWithArgument(Mockito.argThat(Matchers.containsString("w000t")))).thenReturn("yeah!");
+        assertEquals("yeah!", service.methodWithArgument("w000t"));
+        assertNull(service.methodWithArgument("ehm"));
+    }
+
+
+}

File src/test/java/com/atlassian/example/staticsetup/ASetupAndTeardownInRulePattern.java

+package com.atlassian.example.staticsetup;
+
+import org.junit.Rule;
+import org.junit.Test;
+
+public class ASetupAndTeardownInRulePattern {
+
+    @Rule public final ImportantStaticThingRule importantStaticThingSetup = new ImportantStaticThingRule();
+
+    @Test
+    public void testImportantStaticThing() {
+         ImportantStaticThing.get().modifyState();
+    }
+}

File src/test/java/com/atlassian/example/staticsetup/AdvancedImportantStaticThingRule.java

+package com.atlassian.example.staticsetup;
+
+import org.junit.rules.TestWatcher;
+import org.junit.runner.Description;
+
+public class AdvancedImportantStaticThingRule extends TestWatcher {
+
+    @Override
+    protected void starting(Description description) {
+        if (needsImportantStaticThing(description)) {
+            ImportantStaticThing.set(new ImportantStaticThing());
+        }
+    }
+
+    @Override
+    protected void finished(Description description) {
+        ImportantStaticThing.set(null);
+    }
+
+    private boolean needsImportantStaticThing(Description description) {
+        return description.isTest() && description.getAnnotation(NeedsImportantStaticThing.class) != null;
+    }
+}

File src/test/java/com/atlassian/example/staticsetup/AdvancedSetupAndTeardownInRulePattern.java

+package com.atlassian.example.staticsetup;
+
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+public class AdvancedSetupAndTeardownInRulePattern {
+
+    @Rule public final AdvancedImportantStaticThingRule importantStaticThingSetup = new AdvancedImportantStaticThingRule();
+
+    @Test
+    public void testThatDoesNotNeedImportantStaticThing() {
+         assertNull(ImportantStaticThing.get());
+    }
+
+    @Test
+    @NeedsImportantStaticThing
+    public void testThatNeedsImportantStaticThing() {
+        assertNotNull(ImportantStaticThing.get());
+    }
+}

File src/test/java/com/atlassian/example/staticsetup/CopyBeforeAndAfterPattern.java

+package com.atlassian.example.staticsetup;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class CopyBeforeAndAfterPattern {
+
+
+
+    @Before
+    public void setUpImportantStaticThing() {
+        ImportantStaticThing.set(new ImportantStaticThing());
+    }
+
+    @After
+    public void tearDownImportantStaticThing() {
+        ImportantStaticThing.set(null);
+    }
+
+    @Test
+    public void testImportantStaticThing() {
+        ImportantStaticThing.get().modifyState();
+    }
+
+}

File src/test/java/com/atlassian/example/staticsetup/ImportantStaticThing.java

+package com.atlassian.example.staticsetup;
+
+public class ImportantStaticThing {
+
+    private static ImportantStaticThing thing;
+
+    public static void set(ImportantStaticThing aThing) {
+        thing = aThing;
+    }
+
+    public static ImportantStaticThing get() {
+        return thing;
+    }
+
+    private boolean state;
+
+    public void modifyState() {
+        if (state) {
+            throw new IllegalStateException("State already modified!");
+        }
+        this.state = true;
+    }
+}

File src/test/java/com/atlassian/example/staticsetup/ImportantStaticThingRule.java

+package com.atlassian.example.staticsetup;
+
+import org.junit.rules.TestWatcher;
+import org.junit.runner.Description;
+
+public class ImportantStaticThingRule extends TestWatcher {
+
+    @Override
+    protected void starting(Description description) {
+        ImportantStaticThing.set(new ImportantStaticThing());
+    }
+
+    @Override
+    protected void finished(Description description) {
+        ImportantStaticThing.set(null);
+    }
+}

File src/test/java/com/atlassian/example/staticsetup/InnocentTest.java

+package com.atlassian.example.staticsetup;
+
+import org.junit.Test;
+
+public class InnocentTest {
+
+
+    @Test
+    public void testInnocentThings() {
+        // ImportantStaticThing here
+    }
+
+}

File src/test/java/com/atlassian/example/staticsetup/NeedsImportantStaticThing.java

+package com.atlassian.example.staticsetup;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+public @interface NeedsImportantStaticThing {
+}