Add tests for ItsValidateComment

Change-Id: I49014d075f8f5c0c672bae0f1b52a767e3e100d6
diff --git a/hooks-its/src/test/java/com/googlesource/gerrit/plugins/hooks/validation/ItsValidateCommentTest.java b/hooks-its/src/test/java/com/googlesource/gerrit/plugins/hooks/validation/ItsValidateCommentTest.java
new file mode 100644
index 0000000..2421593
--- /dev/null
+++ b/hooks-its/src/test/java/com/googlesource/gerrit/plugins/hooks/validation/ItsValidateCommentTest.java
@@ -0,0 +1,516 @@
+// Copyright (C) 2013 The Android Open Source Project
+//
+// Licensed 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 com.googlesource.gerrit.plugins.hooks.validation;
+
+import static org.easymock.EasyMock.expect;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.regex.Pattern;
+
+import org.eclipse.jgit.lib.Config;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.transport.ReceiveCommand;
+
+import org.junit.runner.RunWith;
+
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+
+import com.google.gerrit.server.config.FactoryModule;
+import com.google.gerrit.server.config.GerritServerConfig;
+import com.google.gerrit.server.events.CommitReceivedEvent;
+import com.google.gerrit.server.git.validators.CommitValidationException;
+import com.google.gerrit.server.git.validators.CommitValidationMessage;
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+
+import com.googlesource.gerrit.plugins.hooks.its.ItsFacade;
+import com.googlesource.gerrit.plugins.hooks.its.ItsName;
+import com.googlesource.gerrit.plugins.hooks.testutil.LoggingMockingTestCase;
+import com.googlesource.gerrit.plugins.hooks.util.IssueExtractor;
+import com.googlesource.gerrit.plugins.hooks.validation.ItsAssociationPolicy;
+import com.googlesource.gerrit.plugins.hooks.validation.ItsValidateComment;
+
+@RunWith(PowerMockRunner.class)
+@PrepareForTest({RevCommit.class})
+public class ItsValidateCommentTest extends LoggingMockingTestCase {
+  private Injector injector;
+  private Config serverConfig;
+  private IssueExtractor issueExtractor;
+  private ItsFacade itsFacade;
+
+  public void testOptional() throws CommitValidationException {
+    List<CommitValidationMessage> ret;
+    ItsValidateComment ivc = injector.getInstance(ItsValidateComment.class);
+    ReceiveCommand command = createMock(ReceiveCommand.class);
+    RevCommit commit = createMock(RevCommit.class);
+    CommitReceivedEvent event = new CommitReceivedEvent(command, null, null,
+        commit, null);
+    expect(serverConfig.getEnum("commentLink", "ItsTestName", "association",
+        ItsAssociationPolicy.OPTIONAL)).andReturn(
+            ItsAssociationPolicy.OPTIONAL).atLeastOnce();
+    replayMocks();
+
+    ret = ivc.onCommitReceived(event);
+
+    assertEmptyList(ret);
+  }
+
+  public void testSuggestedNonMatching() throws CommitValidationException {
+    List<CommitValidationMessage> ret;
+    ItsValidateComment ivc = injector.getInstance(ItsValidateComment.class);
+    ReceiveCommand command = createMock(ReceiveCommand.class);
+    RevCommit commit = createMock(RevCommit.class);
+    CommitReceivedEvent event = new CommitReceivedEvent(command, null, null,
+        commit, null);
+    expect(serverConfig.getEnum("commentLink", "ItsTestName", "association",
+        ItsAssociationPolicy.OPTIONAL)).andReturn(
+            ItsAssociationPolicy.SUGGESTED).atLeastOnce();
+    expect(serverConfig.getString("commentLink", "ItsTestName", "match"))
+        .andReturn("TestPattern").anyTimes();
+    expect(commit.getFullMessage()).andReturn("TestMessage").atLeastOnce();
+    expect(commit.getId()).andReturn(commit).anyTimes();
+    expect(commit.getName()).andReturn("TestCommit").anyTimes();
+    expect(issueExtractor.getIssueIds("TestMessage")).andReturn(
+        new String[] {}).atLeastOnce();
+    expect(itsFacade.name()).andReturn("TestFacade").anyTimes();
+
+    replayMocks();
+
+    ret = ivc.onCommitReceived(event);
+
+    assertEquals("Size of returned CommitValidationMessages does not match",
+        1, ret.size());
+    assertTrue("First CommitValidationMessages does not contain 'Missing " +
+        "issue'",ret.get(0).getMessage().contains("Missing issue"));
+  }
+
+  public void testMandatoryNonMatching() throws CommitValidationException {
+    ItsValidateComment ivc = injector.getInstance(ItsValidateComment.class);
+    ReceiveCommand command = createMock(ReceiveCommand.class);
+    RevCommit commit = createMock(RevCommit.class);
+    CommitReceivedEvent event = new CommitReceivedEvent(command, null, null,
+        commit, null);
+    expect(serverConfig.getEnum("commentLink", "ItsTestName", "association",
+        ItsAssociationPolicy.OPTIONAL)).andReturn(
+            ItsAssociationPolicy.MANDATORY).atLeastOnce();
+    expect(commit.getFullMessage()).andReturn("TestMessage").atLeastOnce();
+    expect(commit.getId()).andReturn(commit).anyTimes();
+    expect(commit.getName()).andReturn("TestCommit").anyTimes();
+    expect(issueExtractor.getIssueIds("TestMessage")).andReturn(
+        new String[] {}).atLeastOnce();
+    expect(itsFacade.name()).andReturn("TestFacade").anyTimes();
+
+    replayMocks();
+
+    try {
+      ivc.onCommitReceived(event);
+      fail("onCommitReceived did not throw any exception");
+    } catch (CommitValidationException e) {
+      assertTrue("Message of thrown CommitValidationException does not "
+          + "contain 'Missing issue'",
+          e.getMessage().contains("Missing issue"));
+    }
+  }
+
+  public void testSuggestedMatchingSingleExisting()
+      throws CommitValidationException, IOException {
+    List<CommitValidationMessage> ret;
+    ItsValidateComment ivc = injector.getInstance(ItsValidateComment.class);
+    ReceiveCommand command = createMock(ReceiveCommand.class);
+    RevCommit commit = createMock(RevCommit.class);
+    CommitReceivedEvent event = new CommitReceivedEvent(command, null, null,
+        commit, null);
+    expect(serverConfig.getEnum("commentLink", "ItsTestName", "association",
+        ItsAssociationPolicy.OPTIONAL)).andReturn(
+            ItsAssociationPolicy.SUGGESTED).atLeastOnce();
+    expect(commit.getFullMessage()).andReturn("bug#4711").atLeastOnce();
+    expect(commit.getId()).andReturn(commit).anyTimes();
+    expect(commit.getName()).andReturn("TestCommit").anyTimes();
+    expect(issueExtractor.getIssueIds("bug#4711")).andReturn(
+        new String[] {"4711"}).atLeastOnce();
+    expect(itsFacade.name()).andReturn("TestFacade").anyTimes();
+    expect(itsFacade.exists("4711")).andReturn(true).atLeastOnce();
+
+    replayMocks();
+
+    ret = ivc.onCommitReceived(event);
+
+    assertEmptyList(ret);
+  }
+
+  public void testMandatoryMatchingSingleExisting()
+      throws CommitValidationException, IOException {
+    List<CommitValidationMessage> ret;
+    ItsValidateComment ivc = injector.getInstance(ItsValidateComment.class);
+    ReceiveCommand command = createMock(ReceiveCommand.class);
+    RevCommit commit = createMock(RevCommit.class);
+    CommitReceivedEvent event = new CommitReceivedEvent(command, null, null,
+        commit, null);
+    expect(serverConfig.getEnum("commentLink", "ItsTestName", "association",
+        ItsAssociationPolicy.OPTIONAL)).andReturn(
+            ItsAssociationPolicy.MANDATORY).atLeastOnce();
+    expect(commit.getFullMessage()).andReturn("bug#4711").atLeastOnce();
+    expect(commit.getId()).andReturn(commit).anyTimes();
+    expect(commit.getName()).andReturn("TestCommit").anyTimes();
+    expect(issueExtractor.getIssueIds("bug#4711")).andReturn(
+        new String[] {"4711"}).atLeastOnce();
+    expect(itsFacade.name()).andReturn("TestFacade").anyTimes();
+    expect(itsFacade.exists("4711")).andReturn(true).atLeastOnce();
+
+    replayMocks();
+
+    ret = ivc.onCommitReceived(event);
+
+    assertEmptyList(ret);
+  }
+
+  public void testSuggestedMatchingSingleNonExisting()
+      throws CommitValidationException, IOException {
+    List<CommitValidationMessage> ret;
+    ItsValidateComment ivc = injector.getInstance(ItsValidateComment.class);
+    ReceiveCommand command = createMock(ReceiveCommand.class);
+    RevCommit commit = createMock(RevCommit.class);
+    CommitReceivedEvent event = new CommitReceivedEvent(command, null, null,
+        commit, null);
+    expect(serverConfig.getEnum("commentLink", "ItsTestName", "association",
+        ItsAssociationPolicy.OPTIONAL)).andReturn(
+            ItsAssociationPolicy.SUGGESTED).atLeastOnce();
+    expect(commit.getFullMessage()).andReturn("bug#4711").atLeastOnce();
+    expect(commit.getId()).andReturn(commit).anyTimes();
+    expect(commit.getName()).andReturn("TestCommit").anyTimes();
+    expect(issueExtractor.getIssueIds("bug#4711")).andReturn(
+        new String[] {"4711"}).atLeastOnce();
+    expect(itsFacade.name()).andReturn("TestFacade").anyTimes();
+    expect(itsFacade.exists("4711")).andReturn(false).atLeastOnce();
+
+    replayMocks();
+
+    ret = ivc.onCommitReceived(event);
+
+    assertEquals("Size of returned CommitValidationMessages does not match",
+        1, ret.size());
+    assertTrue("First CommitValidationMessages does not contain " +
+        "'Non-existing'",ret.get(0).getMessage().contains("Non-existing"));
+    assertTrue("First CommitValidationMessages does not contain '4711'",
+        ret.get(0).getMessage().contains("4711"));
+  }
+
+  public void testMandatoryMatchingSingleNonExisting()
+      throws CommitValidationException, IOException {
+    ItsValidateComment ivc = injector.getInstance(ItsValidateComment.class);
+    ReceiveCommand command = createMock(ReceiveCommand.class);
+    RevCommit commit = createMock(RevCommit.class);
+    CommitReceivedEvent event = new CommitReceivedEvent(command, null, null,
+        commit, null);
+    expect(serverConfig.getEnum("commentLink", "ItsTestName", "association",
+        ItsAssociationPolicy.OPTIONAL)).andReturn(
+            ItsAssociationPolicy.MANDATORY).atLeastOnce();
+    expect(commit.getFullMessage()).andReturn("bug#4711").atLeastOnce();
+    expect(commit.getId()).andReturn(commit).anyTimes();
+    expect(commit.getName()).andReturn("TestCommit").anyTimes();
+    expect(issueExtractor.getIssueIds("bug#4711")).andReturn(
+        new String[] {"4711"}).atLeastOnce();
+    expect(itsFacade.name()).andReturn("TestFacade").anyTimes();
+    expect(itsFacade.exists("4711")).andReturn(false).atLeastOnce();
+
+    replayMocks();
+
+    try {
+      ivc.onCommitReceived(event);
+      fail("onCommitReceived did not throw any exception");
+    } catch (CommitValidationException e) {
+      assertTrue("Message of thrown CommitValidationException does not "
+          + "contain 'Non-existing'", e.getMessage().contains("Non-existing"));
+    }
+  }
+
+  public void testSuggestedMatchingMultiple()
+      throws CommitValidationException, IOException {
+    List<CommitValidationMessage> ret;
+    ItsValidateComment ivc = injector.getInstance(ItsValidateComment.class);
+    ReceiveCommand command = createMock(ReceiveCommand.class);
+    RevCommit commit = createMock(RevCommit.class);
+    CommitReceivedEvent event = new CommitReceivedEvent(command, null, null,
+        commit, null);
+    expect(serverConfig.getEnum("commentLink", "ItsTestName", "association",
+        ItsAssociationPolicy.OPTIONAL)).andReturn(
+            ItsAssociationPolicy.SUGGESTED).atLeastOnce();
+    expect(commit.getFullMessage()).andReturn("bug#4711, bug#42")
+        .atLeastOnce();
+    expect(commit.getId()).andReturn(commit).anyTimes();
+    expect(commit.getName()).andReturn("TestCommit").anyTimes();
+    expect(issueExtractor.getIssueIds("bug#4711, bug#42")).andReturn(
+        new String[] {"4711", "42"}).atLeastOnce();
+    expect(itsFacade.name()).andReturn("TestFacade").anyTimes();
+    expect(itsFacade.exists("4711")).andReturn(true).atLeastOnce();
+    expect(itsFacade.exists("42")).andReturn(true).atLeastOnce();
+
+    replayMocks();
+
+    ret = ivc.onCommitReceived(event);
+
+    assertEmptyList(ret);
+  }
+
+  public void testMandatoryMatchingMultiple()
+      throws CommitValidationException, IOException {
+    List<CommitValidationMessage> ret;
+    ItsValidateComment ivc = injector.getInstance(ItsValidateComment.class);
+    ReceiveCommand command = createMock(ReceiveCommand.class);
+    RevCommit commit = createMock(RevCommit.class);
+    CommitReceivedEvent event = new CommitReceivedEvent(command, null, null,
+        commit, null);
+    expect(serverConfig.getEnum("commentLink", "ItsTestName", "association",
+        ItsAssociationPolicy.OPTIONAL)).andReturn(
+            ItsAssociationPolicy.MANDATORY).atLeastOnce();
+    expect(commit.getFullMessage()).andReturn("bug#4711, bug#42")
+        .atLeastOnce();
+    expect(commit.getId()).andReturn(commit).anyTimes();
+    expect(commit.getName()).andReturn("TestCommit").anyTimes();
+    expect(issueExtractor.getIssueIds("bug#4711, bug#42")).andReturn(
+        new String[] {"4711", "42"}).atLeastOnce();
+    expect(itsFacade.name()).andReturn("TestFacade").anyTimes();
+    expect(itsFacade.exists("4711")).andReturn(true).atLeastOnce();
+    expect(itsFacade.exists("42")).andReturn(true).atLeastOnce();
+
+    replayMocks();
+
+    ret = ivc.onCommitReceived(event);
+
+    assertEmptyList(ret);
+  }
+
+  public void testSuggestedMatchingMultipleOneNonExsting()
+      throws CommitValidationException, IOException {
+    List<CommitValidationMessage> ret;
+    ItsValidateComment ivc = injector.getInstance(ItsValidateComment.class);
+    ReceiveCommand command = createMock(ReceiveCommand.class);
+    RevCommit commit = createMock(RevCommit.class);
+    CommitReceivedEvent event = new CommitReceivedEvent(command, null, null,
+        commit, null);
+    expect(serverConfig.getEnum("commentLink", "ItsTestName", "association",
+        ItsAssociationPolicy.OPTIONAL)).andReturn(
+            ItsAssociationPolicy.SUGGESTED).atLeastOnce();
+    expect(commit.getFullMessage()).andReturn("bug#4711, bug#42")
+        .atLeastOnce();
+    expect(commit.getId()).andReturn(commit).anyTimes();
+    expect(commit.getName()).andReturn("TestCommit").anyTimes();
+    expect(issueExtractor.getIssueIds("bug#4711, bug#42")).andReturn(
+        new String[] {"4711", "42"}).atLeastOnce();
+    expect(itsFacade.name()).andReturn("TestFacade").anyTimes();
+    expect(itsFacade.exists("4711")).andReturn(false).atLeastOnce();
+    expect(itsFacade.exists("42")).andReturn(true).atLeastOnce();
+
+    replayMocks();
+
+    ret = ivc.onCommitReceived(event);
+
+    assertEquals("Size of returned CommitValidationMessages does not match",
+        1, ret.size());
+    assertTrue("First CommitValidationMessages does not contain " +
+        "'Non-existing'",ret.get(0).getMessage().contains("Non-existing"));
+    assertTrue("First CommitValidationMessages does not contain '4711'",
+        ret.get(0).getMessage().contains("4711"));
+    assertFalse("First CommitValidationMessages contains '42', although " +
+        "that bug exists", ret.get(0).getMessage().contains("42"));
+  }
+
+  public void testMandatoryMatchingMultipleOneNonExsting()
+      throws IOException {
+    ItsValidateComment ivc = injector.getInstance(ItsValidateComment.class);
+    ReceiveCommand command = createMock(ReceiveCommand.class);
+    RevCommit commit = createMock(RevCommit.class);
+    CommitReceivedEvent event = new CommitReceivedEvent(command, null, null,
+        commit, null);
+    expect(serverConfig.getEnum("commentLink", "ItsTestName", "association",
+        ItsAssociationPolicy.OPTIONAL)).andReturn(
+            ItsAssociationPolicy.MANDATORY).atLeastOnce();
+    expect(commit.getFullMessage()).andReturn("bug#4711, bug#42")
+        .atLeastOnce();
+    expect(commit.getId()).andReturn(commit).anyTimes();
+    expect(commit.getName()).andReturn("TestCommit").anyTimes();
+    expect(issueExtractor.getIssueIds("bug#4711, bug#42")).andReturn(
+        new String[] {"4711", "42"}).atLeastOnce();
+    expect(itsFacade.name()).andReturn("TestFacade").anyTimes();
+    expect(itsFacade.exists("4711")).andReturn(false).atLeastOnce();
+    expect(itsFacade.exists("42")).andReturn(true).atLeastOnce();
+
+    replayMocks();
+
+    try {
+      ivc.onCommitReceived(event);
+      fail("onCommitReceived did not throw any exception");
+    } catch (CommitValidationException e) {
+      assertTrue("Message of thrown CommitValidationException does not "
+          + "contain 'Non-existing'", e.getMessage().contains("Non-existing"));
+    }
+  }
+
+  public void testSuggestedMatchingMultipleSomeNonExsting()
+      throws CommitValidationException, IOException {
+    List<CommitValidationMessage> ret;
+    ItsValidateComment ivc = injector.getInstance(ItsValidateComment.class);
+    ReceiveCommand command = createMock(ReceiveCommand.class);
+    RevCommit commit = createMock(RevCommit.class);
+    CommitReceivedEvent event = new CommitReceivedEvent(command, null, null,
+        commit, null);
+    expect(serverConfig.getEnum("commentLink", "ItsTestName", "association",
+        ItsAssociationPolicy.OPTIONAL)).andReturn(
+            ItsAssociationPolicy.SUGGESTED).atLeastOnce();
+    expect(commit.getFullMessage()).andReturn("bug#4711, bug#42")
+        .atLeastOnce();
+    expect(commit.getId()).andReturn(commit).anyTimes();
+    expect(commit.getName()).andReturn("TestCommit").anyTimes();
+    expect(issueExtractor.getIssueIds("bug#4711, bug#42")).andReturn(
+        new String[] {"4711", "42"}).atLeastOnce();
+    expect(itsFacade.name()).andReturn("TestFacade").anyTimes();
+    expect(itsFacade.exists("4711")).andReturn(false).atLeastOnce();
+    expect(itsFacade.exists("42")).andReturn(false).atLeastOnce();
+
+    replayMocks();
+
+    ret = ivc.onCommitReceived(event);
+
+    assertEquals("Size of returned CommitValidationMessages does not match",
+        1, ret.size());
+    assertTrue("First CommitValidationMessages does not contain " +
+        "'Non-existing'",ret.get(0).getMessage().contains("Non-existing"));
+    assertTrue("First CommitValidationMessages does not contain '4711'",
+        ret.get(0).getMessage().contains("4711"));
+    assertTrue("First CommitValidationMessages does not contain '42'",
+        ret.get(0).getMessage().contains("42"));
+  }
+
+  public void testMandatoryMatchingMultipleSomeNonExsting()
+      throws IOException {
+    ItsValidateComment ivc = injector.getInstance(ItsValidateComment.class);
+    ReceiveCommand command = createMock(ReceiveCommand.class);
+    RevCommit commit = createMock(RevCommit.class);
+    CommitReceivedEvent event = new CommitReceivedEvent(command, null, null,
+        commit, null);
+    expect(serverConfig.getEnum("commentLink", "ItsTestName", "association",
+        ItsAssociationPolicy.OPTIONAL)).andReturn(
+            ItsAssociationPolicy.MANDATORY).atLeastOnce();
+    expect(commit.getFullMessage()).andReturn("bug#4711, bug#42")
+        .atLeastOnce();
+    expect(commit.getId()).andReturn(commit).anyTimes();
+    expect(commit.getName()).andReturn("TestCommit").anyTimes();
+    expect(issueExtractor.getIssueIds("bug#4711, bug#42")).andReturn(
+        new String[] {"4711", "42"}).atLeastOnce();
+    expect(itsFacade.name()).andReturn("TestFacade").anyTimes();
+    expect(itsFacade.exists("4711")).andReturn(false).atLeastOnce();
+    expect(itsFacade.exists("42")).andReturn(false).atLeastOnce();
+
+    replayMocks();
+
+    try {
+      ivc.onCommitReceived(event);
+      fail("onCommitReceived did not throw any exception");
+    } catch (CommitValidationException e) {
+      assertTrue("Message of thrown CommitValidationException does not "
+          + "contain 'Non-existing'", e.getMessage().contains("Non-existing"));
+    }
+  }
+
+  public void testSuggestedMatchingMultipleIOExceptionIsNonExsting()
+      throws CommitValidationException, IOException {
+    List<CommitValidationMessage> ret;
+    ItsValidateComment ivc = injector.getInstance(ItsValidateComment.class);
+    ReceiveCommand command = createMock(ReceiveCommand.class);
+    RevCommit commit = createMock(RevCommit.class);
+    CommitReceivedEvent event = new CommitReceivedEvent(command, null, null,
+        commit, null);
+    expect(serverConfig.getEnum("commentLink", "ItsTestName", "association",
+        ItsAssociationPolicy.OPTIONAL)).andReturn(
+            ItsAssociationPolicy.SUGGESTED).atLeastOnce();
+    expect(commit.getFullMessage()).andReturn("bug#4711, bug#42")
+        .atLeastOnce();
+    expect(commit.getId()).andReturn(commit).anyTimes();
+    expect(commit.getName()).andReturn("TestCommit").anyTimes();
+    expect(issueExtractor.getIssueIds("bug#4711, bug#42"))
+        .andReturn(new String[] {"4711", "42"}).atLeastOnce();
+    expect(itsFacade.name()).andReturn("TestFacade").anyTimes();
+    expect(itsFacade.exists("4711")).andThrow(new IOException("InjectedEx1"))
+        .atLeastOnce();
+    expect(itsFacade.exists("42")).andReturn(false).atLeastOnce();
+
+    replayMocks();
+
+    ret = ivc.onCommitReceived(event);
+
+    assertEquals("Size of returned CommitValidationMessages does not match",
+        2, ret.size());
+    assertTrue("First CommitValidationMessages does not contain " +
+        "'Failed'",ret.get(0).getMessage().contains("Failed"));
+    assertTrue("First CommitValidationMessages does not contain '4711'",
+        ret.get(0).getMessage().contains("4711"));
+    assertFalse("First CommitValidationMessages contains '42', although " +
+        "that bug exists", ret.get(0).getMessage().contains("42"));
+    assertTrue("Second CommitValidationMessages does not contain " +
+        "'Non-existing'",ret.get(1).getMessage().contains("Non-existing"));
+    assertTrue("Second CommitValidationMessages does not contain '4711'",
+        ret.get(1).getMessage().contains("4711"));
+    assertTrue("Second CommitValidationMessages does not contain '42'",
+        ret.get(1).getMessage().contains("42"));
+
+    assertLogMessageContains("4711");
+  }
+
+  public void assertEmptyList(List<CommitValidationMessage> list) {
+    if (!list.isEmpty()) {
+      StringBuffer sb = new StringBuffer();
+      sb.append("Commit Validation List is not emptyList is not empty, but contains:\n");
+      for (CommitValidationMessage msg : list) {
+        sb.append(msg.getMessage());
+        sb.append("\n");
+      }
+      fail(sb.toString());
+    }
+  }
+
+  private void setupCommonMocks() {
+    expect(issueExtractor.getPattern()).andReturn(Pattern.compile("bug#(\\d+)"))
+        .anyTimes();
+  }
+
+  @Override
+  public void setUp() throws Exception {
+    super.setUp();
+
+    injector = Guice.createInjector(new TestModule());
+
+    setupCommonMocks();
+  }
+
+  private class TestModule extends FactoryModule {
+    @Override
+    protected void configure() {
+      bind(String.class).annotatedWith(ItsName.class)
+          .toInstance("ItsTestName");
+
+      serverConfig = createMock(Config.class);
+      bind(Config.class).annotatedWith(GerritServerConfig.class)
+          .toInstance(serverConfig);
+
+      issueExtractor = createMock(IssueExtractor.class);
+      bind(IssueExtractor.class).toInstance(issueExtractor);
+
+      itsFacade = createMock(ItsFacade.class);
+      bind(ItsFacade.class).toInstance(itsFacade);
+    }
+  }
+}