private void assertReportWrongNumberOfMatchers(TestInterface testObject) {
    Recorder<TestInterface> recorder = TestObject.createRecorder(testObject);

    recorder
        .record(testObject.methodWithArguments((String) recorder.matchObject(Any.ANY), 10))
        .andReturn("value");
  }
  private void assertThrowOnVoidMethod(TestInterface testObject) {
    Recorder<TestInterface> recorder = TestObject.createRecorder(testObject);

    testObject.returnNothing();
    recorder.recordForLastCall().andThrow(new RuntimeException());

    testObject.returnNothing();
  }
  private void assertUseLooseArgumentMatching(TestInterface testObject) {
    String returnedValue = "returnedValue";
    Recorder<TestInterface> recorder = TestObject.createRecorder(testObject);
    recorder
        .record(
            testObject.methodWithArguments(
                (String) recorder.matchObject(Any.ANY), recorder.matchInt(Any.ANY)))
        .andReturn(returnedValue);

    String actual = testObject.methodWithArguments("otherArg", -1);
    ;
    assertEquals(actual, returnedValue);
  }
  private void assertRecordingUseArgumentMatching(TestInterface testObject) {
    String stringArg = "arg";
    int intArg = 11;
    String returnedValue = "returnedValue";
    Recorder<TestInterface> recorder = TestObject.createRecorder(testObject);
    recorder.record(testObject.methodWithArguments(stringArg, intArg)).andReturn(returnedValue);

    String actual = testObject.methodWithArguments("otherArg", -1);
    assertNull(actual);

    actual = testObject.methodWithArguments(stringArg, intArg);
    assertEquals(actual, returnedValue);
  }
  private void assertReturnRecordedValue(TestInterface testObject) {
    String returnValue = "returnValue";
    Integer returnInteger = 10;

    Recorder<TestInterface> recorder = TestObject.createRecorder(testObject);
    recorder
        .record(testObject.returnObject())
        .andReturn(returnValue)
        .record(testObject.returnInteger())
        .andReturn(returnInteger);

    assertEquals(returnValue, testObject.returnObject());
    assertEquals(returnInteger, testObject.returnInteger());
  }
  private void assertEqMatcher(TestInterface testObject) {
    String returnedValue = "returnedValue";
    String stringArg = "stringarg";
    int intArg = -1;
    Recorder<TestInterface> recorder = TestObject.createRecorder(testObject);
    recorder
        .record(
            testObject.methodWithArguments(
                (String) recorder.matchObject(new Eq(stringArg)),
                recorder.matchInt(new Eq(intArg))))
        .andReturn(returnedValue);

    String actual = testObject.methodWithArguments(stringArg, intArg);
    assertEquals(actual, returnedValue);
  }
  private void assertCanModifyReturnValueForPrimitiveType(TestInterface testObject) {
    Recorder<TestInterface> recorder = TestObject.createRecorder(testObject);

    boolean expectedBoolean = true;
    byte expectedByte = 9;
    char expectedChar = 10;
    short expectedShort = 11;
    int expectedInt = 12;
    long expectedLong = 13;
    float expectedFloat = 14.2f;
    double expectedDouble = 15.5d;
    recorder
        .record(testObject.returnBoolean())
        .andReturn(expectedBoolean)
        .record(testObject.returnByte())
        .andReturn(expectedByte)
        .record(testObject.returnChar())
        .andReturn(expectedChar)
        .record(testObject.returnShort())
        .andReturn(expectedShort)
        .record(testObject.returnInt())
        .andReturn(expectedInt)
        .record(testObject.returnLong())
        .andReturn(expectedLong)
        .record(testObject.returnFloat())
        .andReturn(expectedFloat)
        .record(testObject.returnDouble())
        .andReturn(expectedDouble);

    assertEquals(expectedBoolean, testObject.returnBoolean());
    assertEquals(expectedByte, testObject.returnByte());
    assertEquals(expectedChar, testObject.returnChar());
    assertEquals(expectedShort, testObject.returnShort());
    assertEquals(expectedInt, testObject.returnInt());
    assertEquals(expectedLong, testObject.returnLong());
    assertTrue(expectedFloat == testObject.returnFloat());
    assertTrue(expectedDouble == testObject.returnDouble());
  }
  private void assertRecodedExceptionThrown(TestInterface testObject) {
    Recorder<TestInterface> recorder = TestObject.createRecorder(testObject);

    recorder.record(testObject.returnObject()).andThrow(new IllegalArgumentException());
    testObject.returnObject();
  }
 private void assertExceptionThrownIfReturnValueHasWrongType(TestInterface testObject) {
   Recorder<TestInterface> recorder = TestObject.createRecorder(testObject);
   recorder.record(testObject.toString()).andReturn(new Long(10));
 }
 @Test
 public void useLooseArgumentMatchingWithEqMatcherClass() throws Exception {
   TestInterface testObject = TestObject.createTestObject(TestClass.class);
   assertEqMatcher(testObject);
 }
 @Test
 public void shouldReturnNullIfNoRecordingForClass() {
   TestInterface testObject = TestObject.createTestObject(TestClass.class);
   assertDefaultObjectReturnValue(testObject);
 }
 @Test
 public void nullShouldBeMatchedClass() throws Exception {
   TestInterface testObject = TestObject.createTestObject(TestClass.class);
   assertNullParametersMatched(testObject);
 }
 @Test
 public void shouldBeAbleToAlterPrimitiveTypeDefaultValueClass() {
   TestInterface testObject = TestObject.createTestObject(TestClass.class);
   assertCanModifyReturnValueForPrimitiveType(testObject);
 }
 @Test(expected = RuntimeException.class)
 public void shouldThrowExceptionIfSettingAReturnValueOfWrongTypeClass() {
   TestInterface testObject = TestObject.createTestObject(TestClass.class);
   assertExceptionThrownIfReturnValueHasWrongType(testObject);
 }
 @Test(expected = RuntimeException.class)
 public void reportInvalidNumberOfMatchersClass() throws Exception {
   TestInterface testObject = TestObject.createTestObject(TestClass.class);
   assertReportWrongNumberOfMatchers(testObject);
 }
 @Test
 public void shouldReturnDefaultPrimitiveValueIfNoRecordingForClass() {
   TestInterface testObject = TestObject.createTestObject(TestClass.class);
   assertDefaultPrimitiveTypeReturnValues(testObject);
 }
 @Test(expected = RuntimeException.class)
 public void voidMethodWithParamMatchingClass() throws Exception {
   TestInterface testObject = TestObject.createTestObject(TestClass.class);
   assertVoidMethodWithParamMatching(testObject);
 }
 @Test
 public void shouldReturnTheRecorderReturnValueClass() {
   TestInterface testObject = TestObject.createTestObject(TestClass.class);
   assertReturnRecordedValue(testObject);
 }
 @Test
 public void useLooseArgumentMatchingInterface() throws Exception {
   TestInterface testObject = TestObject.createTestObject(TestInterface.class);
   assertUseLooseArgumentMatching(testObject);
 }
 @Test(expected = IllegalArgumentException.class)
 public void recordThrowExceptionShouldThrowExceptionClass() {
   TestInterface testObject = TestObject.createTestObject(TestClass.class);
   assertRecodedExceptionThrown(testObject);
 }
 @Test
 public void useCustomMatcherClass() throws Exception {
   TestInterface testObject = TestObject.createTestObject(TestClass.class);
   assertUseCustomMatcher(testObject);
 }
 @Test(expected = RuntimeException.class)
 public void shouldBeAbleToSetExceptionOnVoidMethodClass() {
   TestInterface testObject = TestObject.createTestObject(TestClass.class);
   assertThrowOnVoidMethod(testObject);
 }
  private void assertDoesNotAllowWrongTypeException(TestInterface testObject) throws IOException {
    Recorder<TestInterface> recorder = TestObject.createRecorder(testObject);

    testObject.throwDeclardeException();
    recorder.recordForLastCall().andThrow(new Exception());
  }
 @Test(expected = RuntimeException.class)
 public void shouldNotAllowToThrowACheckedExceptionOfWrongTypeInterface() throws Exception {
   TestInterface testObject = TestObject.createTestObject(TestInterface.class);
   assertDoesNotAllowWrongTypeException(testObject);
 }
 @Test
 public void useArgumentMatchingForRecordingBehaviorClass() throws Exception {
   TestInterface testObject = TestObject.createTestObject(TestClass.class);
   assertRecordingUseArgumentMatching(testObject);
 }