private static void thatCustomMessageIsAdded()
        {
            // Given
            fflib_ApexMocks mocks    = new fflib_ApexMocks();
            fflib_MyList    mockList = (fflib_MyList)mocks.mock(typeof(fflib_MyList));

            // When
            mockList.add("bob");
            mockList.add("bob");
            mockList.add("bob");
            string customAssertMessage = "Custom message to explain the reason of the verification";

            // Then
            try
            {
                ((fflib_MyList.IList)mocks.verify(mockList, mocks.times(2).description(customAssertMessage))).add(fflib_Match.anyString());
                System.assert(false, "an exception was expected");
            }
            catch (Exception exc)
            {
                string exceptionMessage = exc.getMessage();
                string expectedMessage  = string.format(BASIC_VERIFY_ASSERTION_MESSAGE, new List <string> {
                    "2", "3"
                }) + fflib_MyList.getStubClassName() + ".add(String). " + customAssertMessage + ".";
                System.assertEquals(expectedMessage, exceptionMessage,
                                    "The exception was caught, but the message was not as expected. " +
                                    "Expected: [" + expectedMessage + "],  Actual: [" + exceptionMessage + "].");
            }
        }
        private static void whenVerifyCustomMatchersCanBeUsed()
        {
            // Given
            fflib_ApexMocks mocks    = new fflib_ApexMocks();
            fflib_MyList    mockList = (fflib_MyList)mocks.mock(typeof(fflib_MyList));

            // When
            mockList.get(1);
            mockList.get(2);
            mockList.get(3);
            mockList.get(4);
            mockList.get(5);

            // Then
            ((fflib_MyList.IList)mocks.verify(mockList, mocks.times(3))).get((int)fflib_Match.matches(new isOdd()));
            ((fflib_MyList.IList)mocks.verify(mockList, mocks.times(2))).get((int)fflib_Match.matches(new isEven()));
        }
        private static void whenVerifyWithCombinedMatchersShouldReturnCorrectMethodCallCounts()
        {
            // Given
            fflib_ApexMocks mocks    = new fflib_ApexMocks();
            fflib_MyList    mockList = (fflib_MyList)mocks.mock(typeof(fflib_MyList));

            // When
            mockList.add("bob");
            mockList.add("fred");

            // Then
            ((fflib_MyList.IList)mocks.verify(mockList, mocks.never())).add((string)fflib_Match.allOf(fflib_Match.eq("bob"), fflib_Match.stringContains("re")));
            ((fflib_MyList.IList)mocks.verify(mockList)).add((string)fflib_Match.allOf(fflib_Match.eq("fred"), fflib_Match.stringContains("re")));
            ((fflib_MyList.IList)mocks.verify(mockList, mocks.times(2))).add((string)fflib_Match.anyOf(fflib_Match.eq("bob"), fflib_Match.eq("fred")));
            ((fflib_MyList.IList)mocks.verify(mockList)).add((string)fflib_Match.anyOf(fflib_Match.eq("bob"), fflib_Match.eq("jack")));
            ((fflib_MyList.IList)mocks.verify(mockList, mocks.times(2))).add((string)fflib_Match.noneOf(fflib_Match.eq("jack"), fflib_Match.eq("tim")));
            ((fflib_MyList.IList)mocks.verify(mockList, mocks.times(2))).add((string)fflib_Match.noneOf(fflib_Match.anyOf(fflib_Match.eq("jack"), fflib_Match.eq("jill")),
                                                                                                        fflib_Match.allOf(fflib_Match.eq("tim"), fflib_Match.stringContains("i"))));
            ((fflib_MyList.IList)mocks.verify(mockList, mocks.times(2))).add((string)fflib_Match.isNot(fflib_Match.eq("jack")));
        }
        private static void verifyMultipleMethodCallsWithSameSingleArgument()
        {
            // Given
            fflib_ApexMocks mocks    = new fflib_ApexMocks();
            fflib_MyList    mockList = (fflib_MyList)mocks.mock(typeof(fflib_MyList));

            // When
            mockList.add("bob");
            mockList.add("bob");

            // Then
            ((fflib_MyList.IList)mocks.verify(mockList, mocks.times(2))).add("bob");
        }
        private static void verifyTimesMethodHasBeenCalledWithMatchers()
        {
            // Given
            fflib_ApexMocks mocks    = new fflib_ApexMocks();
            fflib_MyList    mockList = (fflib_MyList)mocks.mock(typeof(fflib_MyList));

            // When
            mockList.add("bob1");
            mockList.add("bob2");
            mockList.add("bob3");

            // Then
            ((fflib_MyList.IList)mocks.verify(mockList, mocks.times(3))).add(fflib_Match.anyString());
        }
        private static void verifyTimesMethodHasBeenCalled()
        {
            // Given
            fflib_ApexMocks mocks    = new fflib_ApexMocks();
            fflib_MyList    mockList = (fflib_MyList)mocks.mock(typeof(fflib_MyList));

            // When
            mockList.add("bob");
            mockList.add("bob");
            mockList.add("bob");

            // Then
            ((fflib_MyList.IList)mocks.verify(mockList, mocks.times(3))).add("bob");
        }
        private static void whenVerifyMultipleCallsWithMatchersShouldReturnCorrectMethodCallCounts()
        {
            // Given
            fflib_ApexMocks mocks    = new fflib_ApexMocks();
            fflib_MyList    mockList = (fflib_MyList)mocks.mock(typeof(fflib_MyList));

            // When
            mockList.add("bob");
            mockList.add("fred");

            // Then
            ((fflib_MyList.IList)mocks.verify(mockList, mocks.times(2))).add(fflib_Match.anyString());
            ((fflib_MyList.IList)mocks.verify(mockList)).add("fred");
            ((fflib_MyList.IList)mocks.verify(mockList)).add(fflib_Match.stringContains("fred"));
        }
        private static void thatVerifyTimesMethodFailsWhenCalledMoreTimesWithMatchers()
        {
            // Given
            fflib_ApexMocks mocks    = new fflib_ApexMocks();
            fflib_MyList    mockList = (fflib_MyList)mocks.mock(typeof(fflib_MyList));

            // When
            mockList.add("bob");
            mockList.add("bob");
            mockList.add("bob");

            // Then
            try
            {
                ((fflib_MyList.IList)mocks.verify(mockList, mocks.times(2))).add(fflib_Match.anyString());
                System.assert(false, "an exception was expected");
            }
            catch (Exception exc)
            {
                assertFailMessage(exc.getMessage(), 2, 3);
            }
        }