Repository: financialforcedev/fflib-apex-mocks Branch: master Commit: 0f37f7677970 Files: 85 Total size: 489.9 KB Directory structure: gitextract_1z2z19yr/ ├── .github/ │ ├── ISSUE_TEMPLATE/ │ │ ├── bug_report.md │ │ └── feature_request.md │ └── workflows/ │ ├── deploy.and.test.yml │ └── manage.sf.api.versions.yml ├── .gitignore ├── LICENSE ├── README.md ├── config/ │ └── project-scratch-def.json ├── sfdx-project.json └── sfdx-source/ └── apex-mocks/ ├── main/ │ └── classes/ │ ├── fflib_Answer.cls │ ├── fflib_Answer.cls-meta.xml │ ├── fflib_AnyOrder.cls │ ├── fflib_AnyOrder.cls-meta.xml │ ├── fflib_ApexMocks.cls │ ├── fflib_ApexMocks.cls-meta.xml │ ├── fflib_ApexMocksConfig.cls │ ├── fflib_ApexMocksConfig.cls-meta.xml │ ├── fflib_ApexMocksUtils.cls │ ├── fflib_ApexMocksUtils.cls-meta.xml │ ├── fflib_ArgumentCaptor.cls │ ├── fflib_ArgumentCaptor.cls-meta.xml │ ├── fflib_IDGenerator.cls │ ├── fflib_IDGenerator.cls-meta.xml │ ├── fflib_IMatcher.cls │ ├── fflib_IMatcher.cls-meta.xml │ ├── fflib_InOrder.cls │ ├── fflib_InOrder.cls-meta.xml │ ├── fflib_Inheritor.cls │ ├── fflib_Inheritor.cls-meta.xml │ ├── fflib_InvocationOnMock.cls │ ├── fflib_InvocationOnMock.cls-meta.xml │ ├── fflib_Match.cls │ ├── fflib_Match.cls-meta.xml │ ├── fflib_MatcherDefinitions.cls │ ├── fflib_MatcherDefinitions.cls-meta.xml │ ├── fflib_MatchersReturnValue.cls │ ├── fflib_MatchersReturnValue.cls-meta.xml │ ├── fflib_MethodArgValues.cls │ ├── fflib_MethodArgValues.cls-meta.xml │ ├── fflib_MethodCountRecorder.cls │ ├── fflib_MethodCountRecorder.cls-meta.xml │ ├── fflib_MethodReturnValue.cls │ ├── fflib_MethodReturnValue.cls-meta.xml │ ├── fflib_MethodReturnValueRecorder.cls │ ├── fflib_MethodReturnValueRecorder.cls-meta.xml │ ├── fflib_MethodVerifier.cls │ ├── fflib_MethodVerifier.cls-meta.xml │ ├── fflib_QualifiedMethod.cls │ ├── fflib_QualifiedMethod.cls-meta.xml │ ├── fflib_QualifiedMethodAndArgValues.cls │ ├── fflib_QualifiedMethodAndArgValues.cls-meta.xml │ ├── fflib_System.cls │ ├── fflib_System.cls-meta.xml │ ├── fflib_VerificationMode.cls │ └── fflib_VerificationMode.cls-meta.xml └── test/ └── classes/ ├── fflib_AnswerTest.cls ├── fflib_AnswerTest.cls-meta.xml ├── fflib_AnyOrderTest.cls ├── fflib_AnyOrderTest.cls-meta.xml ├── fflib_ApexMocksTest.cls ├── fflib_ApexMocksTest.cls-meta.xml ├── fflib_ApexMocksUtilsTest.cls ├── fflib_ApexMocksUtilsTest.cls-meta.xml ├── fflib_ArgumentCaptorTest.cls ├── fflib_ArgumentCaptorTest.cls-meta.xml ├── fflib_IDGeneratorTest.cls ├── fflib_IDGeneratorTest.cls-meta.xml ├── fflib_InOrderTest.cls ├── fflib_InOrderTest.cls-meta.xml ├── fflib_InheritorTest.cls ├── fflib_InheritorTest.cls-meta.xml ├── fflib_MatchTest.cls ├── fflib_MatchTest.cls-meta.xml ├── fflib_MatcherDefinitionsTest.cls ├── fflib_MatcherDefinitionsTest.cls-meta.xml ├── fflib_MethodArgValuesTest.cls ├── fflib_MethodArgValuesTest.cls-meta.xml ├── fflib_MyList.cls ├── fflib_MyList.cls-meta.xml ├── fflib_QualifiedMethodAndArgValuesTest.cls ├── fflib_QualifiedMethodAndArgValuesTest.cls-meta.xml ├── fflib_QualifiedMethodTest.cls ├── fflib_QualifiedMethodTest.cls-meta.xml ├── fflib_SystemTest.cls └── fflib_SystemTest.cls-meta.xml ================================================ FILE CONTENTS ================================================ ================================================ FILE: .github/ISSUE_TEMPLATE/bug_report.md ================================================ --- name: Bug report about: Create a report to help us improve title: '' labels: '' assignees: '' --- **Describe the bug** (A clear and concise description of what the bug is.) **To Reproduce** (Please provide a public github repo with a full SFDX project that demonstrates the problem. If the repro case can be followed with a single example Apex class against a scratch org with just the fflib-apex-mocks project deployed into it, you don't need to provide a github repo) Steps to reproduce the behavior: 1. Create a scratch org as follows.... 2. Run the following Anonymous Apex.... 3. See error **Expected behavior** A clear and concise description of what you expected to happen. **Screenshots and text of error observed** If applicable, add screenshots to help explain your problem. Also, paste the text of the raw error into the issue as well so that it can be found by others via search. **Version** Did you try to reproduce the problem against the latest fflib-apex-mocks code? ================================================ FILE: .github/ISSUE_TEMPLATE/feature_request.md ================================================ --- name: Feature request about: Suggest an idea for this project title: '' labels: '' assignees: '' --- **Is your feature request related to a problem? Please describe.** A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] **Describe the solution you'd like** A clear and concise description of what you want to happen. **Describe alternatives you've considered** A clear and concise description of any alternative solutions or features you've considered. **Additional context** Add any other context or screenshots about the feature request here. ================================================ FILE: .github/workflows/deploy.and.test.yml ================================================ name: Create a Scratch Org, Push Source and Run Apex Tests on: push: pull_request_target: workflow_dispatch: jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 #Check out this repo with: ref: ${{github.event.pull_request.head.ref}} repository: ${{github.event.pull_request.head.repo.full_name}} - name: Install SF CLI and authorize DevHub uses: apex-enterprise-patterns/setup-sfdx@v2 #We're using a fork of https://github.com/sfdx-actions/setup-sfdx for safety with: sfdx-auth-url: ${{ secrets.DEVHUB_SFDXURL }} - name: Setup the config parameters needed run: sf config set target-dev-hub SFDX-ENV --global #Even though the setup-sfdx action uses --setdefaultdevhubusername, it doesn't seem to stick since it uses --setdefaultusername so we brute force it here - name: Create the scratch org run: sf org create scratch --definition-file config/project-scratch-def.json --set-default --duration-days 1 --no-track-source - name: Deploy and compile the codebase run: sf project deploy start - name: Run the core framework tests run: sf apex run test --wait 5 - name: Destroy scratch org run: sf org delete scratch --no-prompt if: always() ================================================ FILE: .github/workflows/manage.sf.api.versions.yml ================================================ name: Manage SF API Versions on: workflow_dispatch: inputs: api-version: description: 'api version in the format XX e.g 58' required: true type: string jobs: update: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - uses: apex-enterprise-patterns/manage-sf-api-version@v1.0.0 with: api-version: ${{inputs.api-version}} - uses: peter-evans/create-pull-request@v5 with: title: 'Bump API Versions to ${{inputs.api-version}}.0' body: 'Automatically bumped by GitHub Actions ' branch: 'devops/bump-api-versions-v${{inputs.api-version}}.0' commit-message: 'chore: bump api to v${{inputs.api-version}}.0' ================================================ FILE: .gitignore ================================================ # General Project related .DS_Store target/ temp/ /deploy/* /debug/ **/dep-dir.txt *.prefs build.properties /sfdx-source/apex-mocks/main/default # MavensMate IDE related *mm.log *.sublime-build *.sublime-project *.sublime-settings *.sublime-workspace .sublime-project .tm_properties # Eclipse IDE Related .project .settings/ salesforce.schema Referenced Packages/ # VS Code IDE Related .vscode/ .history/ # Illuminated Cloud Related .idea/ IlluminatedCloud # SFDX Related .sfdx/ .sf/ sfdx-source/untracked/ .execanon # NPM Related package.json /node_modules package-lock.json sfdx-source/group* research/ ================================================ FILE: LICENSE ================================================ Copyright (c), FinancialForce.com, inc All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of the FinancialForce.com, inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================ FILE: README.md ================================================ # FFLib ApexMocks Framework ![Push Source and Run Apex Tests](https://github.com/apex-enterprise-patterns/fflib-apex-mocks/workflows/Create%20a%20Scratch%20Org,%20Push%20Source%20and%20Run%20Apex%20Tests/badge.svg) ApexMocks is a mocking framework for the Salesforce Lightning Apex language. It derives its inspiration from the well known Java mocking framework [Mockito](https://site.mockito.org/) Deploy to Salesforce ## Using ApexMocks on the Salesforce Lightning Platform ApexMocks allows you to write tests to both verify behavior and stub dependencies. An assumption is made that you are using some form of [Dependency Injection](http://en.wikipedia.org/wiki/Dependency_injection) - for example passing dependencies via a constructor: ```Java public MyClass(ClassA.IClassA dependencyA, ClassB.IClassB dependencyB) ``` This allows you to pass mock implementations of dependencies A and B when you want to unit test MyClass. Lets assume we've written our own list interface fflib_MyList.IList that we want to either verify or stub: ```Java public class fflib_MyList implements IList { public interface IList { void add(String value); String get(Integer index); void clear(); Boolean isEmpty(); } } ``` ### verify() behaviour verification ```Java // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList.IList mockList = (fflib_MyList.IList)mocks.mock(fflib_MyList.class); // When mockList.add('bob'); // Then ((fflib_MyList.IList) mocks.verify(mockList)).add('bob'); ((fflib_MyList.IList) mocks.verify(mockList, fflib_ApexMocks.NEVER)).clear(); ``` If the method wasn't called the expected number of times, or with the expected arguments, verify will throw an exception. The exception message contains details of the expected and actual invocations: ``` EXPECTED COUNT: 1 ACTUAL COUNT: 0 METHOD: EmailService__sfdc_ApexStub.sendTo(String) --- ACTUAL ARGS: ("user-two@example.com") --- EXPECTED ARGS: [[contains "user-one"]] ``` ### when() dependency stubbing ```Java fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList.IList mockList = (fflib_MyList.IList)mocks.mock(fflib_MyList.class); mocks.startStubbing(); mocks.when(mockList.get(0)).thenReturn('bob'); mocks.when(mockList.get(1)).thenReturn('fred'); mocks.stopStubbing(); ``` ## Utilties ### Setting a read-only field, such as a formula ```Java Account acc = new Account(); Integer mockFormulaResult = 10; acc = (Account)fflib_ApexMocksUtils.setReadOnlyFields( acc, Account.class, new Map {Account.Your_Formula_Field__c => mockFormulaResult} ); System.assertEquals(mockFormulaResult, acc.Your_Formula_Field__c); ``` ## Stub API Using Salesforce's [Stub API](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_testing_stub_api.htm), stub objects are generated dynamically at run time. ```Java fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); ``` ## Documentation * [ApexMocks Framework Tutorial](http://code4cloud.wordpress.com/2014/05/06/apexmocks-framework-tutorial/) * [Simple Dependency Injection](http://code4cloud.wordpress.com/2014/05/09/simple-dependency-injection/) * [ApexMocks Generator](http://code4cloud.wordpress.com/2014/05/15/using-apex-mocks-generator-to-create-mock-class-definitions/) * [Behaviour Verification](http://code4cloud.wordpress.com/2014/05/15/writing-behaviour-verification-unit-tests/) * [Stubbing Dependencies](http://code4cloud.wordpress.com/2014/05/15/stubbing-dependencies-in-a-unit-test/) * [Supported Features](http://code4cloud.wordpress.com/2014/05/15/apexmocks-supported-features/) * [New Improved apex-mocks-generator](http://code4cloud.wordpress.com/2014/06/27/new-improved-apex-mocks-generator/) * [ApexMocks Improvements - exception stubbing, base classes and more](http://code4cloud.wordpress.com/2014/11/05/apexmocks-improvements-exception-stubbing-inner-interfaces-and-mock-base-classes/) * [Matchers](http://superdupercode.blogspot.co.uk/2016/03/apex-mocks-matchers.html) * [ApexMock blogs from Jesse Altman](http://jessealtman.com/tag/apexmocks/) * [Order of calls verification](https://xonoxforce.wordpress.com/2017/03/26/inorder-verify/) * [Answering](https://xonoxforce.wordpress.com/2017/03/31/answering-with-apex-mocks/) * [Counters](https://xonoxforce.wordpress.com/2017/04/01/counters-in-apex-mocks-verifications/) * [Troubleshooting](https://salesforce.stackexchange.com/questions/252460/my-apexmocks-arent-working-what-could-be-wrong) ================================================ FILE: config/project-scratch-def.json ================================================ { "orgName": "apex-mocks", "edition": "Developer", "settings": { "lightningExperienceSettings": { "enableS1DesktopEnabled": true } } } ================================================ FILE: sfdx-project.json ================================================ { "packageDirectories": [ { "path": "sfdx-source/apex-mocks", "default": true } ], "namespace": "", "sfdcLoginUrl": "https://login.salesforce.com", "sourceApiVersion": "63.0" } ================================================ FILE: sfdx-source/apex-mocks/main/classes/fflib_Answer.cls ================================================ /* Copyright (c) 2017 FinancialForce.com, inc. All rights reserved. */ /** * Interface for the answering framework. * This interface must be implemented inside the test class and implement the call back method answer. * @group Core */ @NamespaceAccessible public interface fflib_Answer { /** * Method to be implemented in the test class to implement the call back method. * @param invocation The invocation on the mock. * @throws The exception to be thrown. * @return The value to be returned. */ Object answer(fflib_InvocationOnMock invocation); } ================================================ FILE: sfdx-source/apex-mocks/main/classes/fflib_Answer.cls-meta.xml ================================================ 63.0 Active ================================================ FILE: sfdx-source/apex-mocks/main/classes/fflib_AnyOrder.cls ================================================ /* Copyright (c) 2017 FinancialForce.com, inc. All rights reserved. */ /** * 'Classic' invocation verifier - checks that a method was called with the given arguments the expected number of times. * The order of method calls is not important. * @group Core */ @NamespaceAccessible public class fflib_AnyOrder extends fflib_MethodVerifier { /* * Verifies a method was invoked the expected number of times, with the expected arguments. * @param qualifiedMethod The method to be verified. * @param methodArg The arguments of the method that needs to be verified. * @param verificationMode The verification mode that holds the setting about how the verification should be performed. */ protected override void verify( fflib_QualifiedMethod qm, fflib_MethodArgValues expectedArguments, fflib_VerificationMode verificationMode) { List expectedMatchers = fflib_Match.Matching ? fflib_Match.getAndClearMatchers(expectedArguments.argValues.size()) : null; List actualArguments = fflib_MethodCountRecorder.getMethodArgumentsByTypeName().get(qm); Integer methodCount = getMethodCount(expectedArguments, expectedMatchers, actualArguments); String qualifier = ''; Integer expectedCount = null; if((verificationMode.VerifyMin == verificationMode.VerifyMax) && methodCount != verificationMode.VerifyMin) { expectedCount = verificationMode.VerifyMin; } else if (verificationMode.VerifyMin != null && verificationMode.VerifyMin > methodCount) { expectedCount = verificationMode.VerifyMin; qualifier = ' or more times'; } else if (verificationMode.VerifyMax != null && verificationMode.VerifyMax < methodCount) { expectedCount = verificationMode.VerifyMax; qualifier = ' or fewer times'; } if (expectedCount != null) { throwException(qm, '', expectedCount, qualifier, methodCount, verificationMode.CustomAssertMessage, expectedArguments, expectedMatchers, actualArguments); } } private Integer getMethodCount(fflib_MethodArgValues methodArg, List matchers, List methodArgs) { Integer retval = 0; if (methodArgs != null) { if (matchers != null) { for (fflib_MethodArgValues args : methodArgs) { if (fflib_Match.matchesAllArgs(args, matchers)) { capture(matchers); retval ++; } } } else { return countCalls(methodArgs, methodArg); } } return retval; } private Integer countCalls(List methodArgs, fflib_MethodArgValues methodArg) { Integer count = 0; for(fflib_MethodArgValues arg: methodArgs) { if( arg == methodArg) count++; } return count; } /* * Method that validate the verification mode used in the verify. * Not all the methods from the fflib_VerificationMode are implemented for the different classes that extends the fflib_MethodVerifier. * The error is thrown at run time, so this method is called in the method that actually performs the verify. * @param verificationMode The verification mode that have to been verified. * @throws Exception with message for the fflib_VerificationMode not implemented. */ protected override void validateMode(fflib_VerificationMode verificationMode) { if(verificationMode.Method == fflib_VerificationMode.ModeName.CALLS) { throw new fflib_ApexMocks.ApexMocksException( 'The calls() method is available only in the InOrder Verification.'); } } } ================================================ FILE: sfdx-source/apex-mocks/main/classes/fflib_AnyOrder.cls-meta.xml ================================================ 63.0 Active ================================================ FILE: sfdx-source/apex-mocks/main/classes/fflib_ApexMocks.cls ================================================ /* Copyright (c) 2014-2017 FinancialForce.com, inc. All rights reserved. */ /** * @group Core */ @NamespaceAccessible public with sharing class fflib_ApexMocks implements System.StubProvider { public static final Integer NEVER = 0; private final fflib_MethodCountRecorder methodCountRecorder; private final fflib_MethodReturnValueRecorder methodReturnValueRecorder; private fflib_MethodVerifier methodVerifier; private fflib_VerificationMode verificationMode; private fflib_Answer myAnswer; public Boolean verifying { get; set; } public Boolean Stubbing { get { return methodReturnValueRecorder.Stubbing; } private set; } public List DoThrowWhenExceptions { get { return methodReturnValueRecorder.DoThrowWhenExceptions; } set { methodReturnValueRecorder.DoThrowWhenExceptions = value; } } /** * Construct an ApexMocks instance. */ @NamespaceAccessible public fflib_ApexMocks() { this.verifying = false; this.methodCountRecorder = new fflib_MethodCountRecorder(); this.verificationMode = new fflib_VerificationMode(); this.methodVerifier = new fflib_AnyOrder(); this.methodReturnValueRecorder = new fflib_MethodReturnValueRecorder(); this.methodReturnValueRecorder.Stubbing = false; } /** * Creates mock object of given class or interface. * @param classToMock class or interface to mock. * @return mock object. */ @NamespaceAccessible public Object mock(Type classToMock) { return Test.createStub(classToMock, this); } /** * Inherited from StubProvider. * @param stubbedObject The stubbed object. * @param stubbedMethodName The name of the invoked method. * @param returnType The return type of the invoked method. * @param listOfParamTypes A list of the parameter types of the invoked method. * @param listOfParamNames A list of the parameter names of the invoked method. * @param listOfArgs The actual argument values passed into this method at runtime. * @return The stubbed return value. Null by default, unless you prepared one that matches this method and argument values in stubbing. */ @NamespaceAccessible public Object handleMethodCall(Object stubbedObject, String stubbedMethodName, Type returnType, List listOfParamTypes, List listOfParamNames, List listOfArgs) { return mockNonVoidMethod(stubbedObject, stubbedMethodName, listOfParamTypes, listOfArgs); } @NamespaceAccessible public static String extractTypeName(Object mockInstance) { return String.valueOf(mockInstance).split(':').get(0); } /** * Verify a method was called on a mock object. * @param mockInstance The mock object instance. * @return The mock object instance. */ @NamespaceAccessible public Object verify(Object mockInstance) { return verify(mockInstance, this.times(1)); } /** * Verify a method was called on a mock object. * @param mockInstance The mock object instance. * @param verificationMode Defines the constraints for performing the verification (e.g. the minimum and maximum expected invocation counts). * @return The mock object instance. */ @NamespaceAccessible public Object verify(Object mockInstance, fflib_VerificationMode verificationMode) { this.verifying = true; this.verificationMode = verificationMode; return mockInstance; } /** * Verify a method was called on a mock object. * @param mockInstance The mock object instance. * @param times The number of times you expect the method to have been called. * @return The mock object instance. */ @NamespaceAccessible public Object verify(Object mockInstance, Integer times) { return verify(mockInstance, this.times(times)); } /** * Verfiy a method was called on a mock object. * @param mockInvocation The invocation on the mock containing information about the method and the arguments. */ public void verifyMethodCall(fflib_InvocationOnMock mockInvocation) { this.methodVerifier.verifyMethodCall(mockInvocation, verificationMode); this.methodVerifier = new fflib_AnyOrder(); this.verifying = false; } /** * Tell ApexMocks framework you are about to start stubbing using when() calls. */ @NamespaceAccessible public void startStubbing() { methodReturnValueRecorder.Stubbing = true; } /** * Tell ApexMocks framework you are about to stop stubbing using when() calls. */ @NamespaceAccessible public void stopStubbing() { methodReturnValueRecorder.Stubbing = false; } /** * Setup when stubbing for a mock object instance. * @param ignoredRetVal This is the return value from the method called on the mockInstance, and is ignored here since we are about to setup * the stubbed return value using thenReturn() (see MethodReturnValue class below). */ @NamespaceAccessible public fflib_MethodReturnValue when(Object ignoredRetVal) { return methodReturnValueRecorder.MethodReturnValue; } /** * Record a method was called on a mock object. * @param mockInvocation The invocation on the mock containing information about the method and the arguments. */ public void recordMethod(fflib_InvocationOnMock mockInvocation) { methodCountRecorder.recordMethod(mockInvocation); } /** * Prepare a stubbed method return value. * @param mockInvocation The invocation on the mock containing information about the method and the arguments. * @return The MethodReturnValue instance. */ public fflib_MethodReturnValue prepareMethodReturnValue(fflib_InvocationOnMock mockInvocation) { return methodReturnValueRecorder.prepareMethodReturnValue(mockInvocation); } /** * Get the method return value for the given method call. * @param mockInvocation The invocation on the mock containing information about the method and the arguments. * @return The MethodReturnValue instance. */ public fflib_MethodReturnValue getMethodReturnValue(fflib_InvocationOnMock mockInvocation) { return methodReturnValueRecorder.getMethodReturnValue(mockInvocation); } /** * Setup exception stubbing for a void method. * @param e The exception to throw. * @param mockInstance The mock object instance. */ @NamespaceAccessible public Object doThrowWhen(Exception e, Object mockInstance) { methodReturnValueRecorder.prepareDoThrowWhenExceptions(new List{e}); return mockInstance; } /** * Setup exception stubbing for a void method. * @param exps The list of exceptions to throw. * @param mockInstance The mock object instance. */ @NamespaceAccessible public Object doThrowWhen(List exps, Object mockInstance) { methodReturnValueRecorder.prepareDoThrowWhenExceptions(exps); return mockInstance; } /** * Setup answer stubbing for a void method. * @param answer The answer to invoke. * @param mockInstance The mock object instance. */ @NamespaceAccessible public Object doAnswer(fflib_Answer answer, Object mockInstance) { this.myAnswer = answer; return mockInstance; } /** * Mock a void method. Called by generated mock instance classes, not directly by a developers * code. * @param mockInstance The mock object instance. * @param methodName The method for which to prepare a return value. * @param methodArgTypes The method argument types for which to prepare a return value. * @param methodArgValues The method argument values for which to prepare a return value. */ public void mockVoidMethod(Object mockInstance, String methodName, List methodArgTypes, List methodArgValues) { mockNonVoidMethod(mockInstance, methodName, methodArgTypes, methodArgValues); } /** * Mock a non-void method. Called by generated mock instance classes, not directly by a developers * code. * @param mockInstance The mock object instance. * @param methodName The method for which to prepare a return value. * @param methodArgTypes The method argument types for which to prepare a return value. * @param methodArgValues The method argument values for which to prepare a return value. */ public Object mockNonVoidMethod(Object mockInstance, String methodName, List methodArgTypes, List methodArgValues) { fflib_QualifiedMethod qm = new fflib_QualifiedMethod(extractTypeName(mockInstance), methodName, methodArgTypes, mockInstance); fflib_MethodArgValues argValues = new fflib_MethodArgValues(methodArgValues); fflib_InvocationOnMock invocation = new fflib_InvocationOnMock(qm, argValues, mockInstance); if (this.verifying) { verifyMethodCall(invocation); } else if (Stubbing) { fflib_MethodReturnValue methotReturnValue = prepareMethodReturnValue(invocation); if(DoThrowWhenExceptions != null) { methotReturnValue.thenThrowMulti(DoThrowWhenExceptions); DoThrowWhenExceptions = null; return null; } if(this.myAnswer != null) { methotReturnValue.thenAnswer(this.myAnswer); this.myAnswer = null; return null; } return null; } else { recordMethod(invocation); return returnValue(invocation); } return null; } /** * Custom exception class for ApexMocks */ @NamespaceAccessible public class ApexMocksException extends Exception { } private Object returnValue(fflib_InvocationOnMock invocation) { fflib_MethodReturnValue methodReturnValue = getMethodReturnValue(invocation); if (methodReturnValue != null) { if(methodReturnValue.Answer == null) { throw new fflib_ApexMocks.ApexMocksException( 'The stubbing is not correct, no return values have been set.'); } Object returnedValue = methodReturnValue.Answer.answer(invocation); if(returnedValue == null) { return null; } if (returnedValue instanceof Exception) { throw ((Exception) returnedValue); } return returnedValue; } return null; } /** * Sets how many times the method is expected to be called. * For InOrder verification we copy Mockito behavior which is as follows; *
    *
  • Consume the specified number of matching invocations, ignoring non-matching invocations in between
  • *
  • Fail an assert if the very next invocation matches, but additional matches can still exist so long as at least one non-matching invocation exists before them
  • *
* For example if you had a(); a(); b(); a(); * then inOrder.verify(myMock, 2)).a(); or inOrder.verify(myMock, 3)).a(); would pass but not inOrder.verify(myMock, 1)).a(); * @param times The number of times you expect the method to have been called. * @return The fflib_VerificationMode object instance with the proper settings. */ @NamespaceAccessible public fflib_VerificationMode times(Integer times) { return new fflib_VerificationMode().times(times); } /** * Sets how many times the method is expected to be called for an InOrder verifier. Available Only with the InOrder verification. * A verification mode using calls will not fail if the method is called more times than expected. * @param times The number of times you expect the method to have been called in the InOrder verifying ( no greedy verify). * @return The fflib_VerificationMode object instance with the proper settings. */ @NamespaceAccessible public fflib_VerificationMode calls(Integer times) { return new fflib_VerificationMode().calls(times); } /** * Sets a custom assert message for the verify. * @param customAssertMessage The custom message for the assert in case the assert is false. The custom message is queued to the default message. * @return The fflib_VerificationMode object instance with the proper settings. */ @NamespaceAccessible public fflib_VerificationMode description(String customAssertMessage) { return new fflib_VerificationMode().description(customAssertMessage); } /** * Sets the minimum number of times the method is expected to be called. * With the InOrder verification it performs a greedy verification, which means it would consume all the instances of the method verified. * @param atLeastTimes The minimum number of times you expect the method to have been called. * @return The fflib_VerificationMode object instance with the proper settings. */ @NamespaceAccessible public fflib_VerificationMode atLeast(Integer atLeastTimes) { return new fflib_VerificationMode().atLeast(atLeastTimes); } /** * Sets the maximum number of times the method is expected to be called. Not available in the InOrder verification. * @param atMostTimes The maximum number of times the method is expected to be called. * @return The fflib_VerificationMode object instance with the proper settings. */ @NamespaceAccessible public fflib_VerificationMode atMost(Integer atMostTimes) { return new fflib_VerificationMode().atMost(atMostTimes); } /** * Sets that the method is called at least once. * With the InOrder verification it performs a greedy verification, which means it would consume all the instances of the method verified. * @return The fflib_VerificationMode object instance with the proper settings. */ @NamespaceAccessible public fflib_VerificationMode atLeastOnce() { return new fflib_VerificationMode().atLeastOnce(); } /** * Sets the range of how many times the method is expected to be called. Not available in the InOrder verification. * @param atLeastTimes The minimum number of times you expect the method to have been called. * @param atMostTimes The maximum number of times the method is expected to be called. * @return The fflib_VerificationMode object instance with the proper settings. */ @NamespaceAccessible public fflib_VerificationMode between(Integer atLeastTimes, Integer atMostTimes) { return new fflib_VerificationMode().between(atLeastTimes, atMostTimes); } /** * Sets that the method is not expected to be called. * @return The fflib_VerificationMode object instance with the proper settings. */ @NamespaceAccessible public fflib_VerificationMode never() { return new fflib_VerificationMode().never(); } /** * Sets the fflib_VerificationMode object. * To internal use only. * Used to pass the verification mode that has been set in the verify of the fflib_InOrder class. * @return The fflib_VerificationMode object instance with the proper settings. */ public void setOrderedVerifier(fflib_InOrder verifyOrderingMode) { this.methodVerifier = verifyOrderingMode; } /** * A simple override to suppress the default toString logic, which is noisy and rarely useful. * In some cases, the Salesforce default implementation of toString here can cause internal Salesforce errors * if it has circular references. * @return "fflib_ApexMocks" String literal */ public override String toString() { return 'fflib_ApexMocks'; } } ================================================ FILE: sfdx-source/apex-mocks/main/classes/fflib_ApexMocks.cls-meta.xml ================================================ 63.0 Active ================================================ FILE: sfdx-source/apex-mocks/main/classes/fflib_ApexMocksConfig.cls ================================================ /* * Copyright (c) 2017 FinancialForce.com, inc. All rights reserved. */ @IsTest @NamespaceAccessible public class fflib_ApexMocksConfig { /** * When false, stubbed behaviour and invocation counts are shared among all test spies. * - See fflib_ApexMocksTest.thatMultipleInstancesCanBeMockedDependently * - This is the default for backwards compatibility. * When true, each test spy instance has its own stubbed behaviour and invocations. * - See fflib_ApexMocksTest.thatMultipleInstancesCanBeMockedIndependently */ @NamespaceAccessible public static Boolean HasIndependentMocks {get; set;} static { HasIndependentMocks = false; } } ================================================ FILE: sfdx-source/apex-mocks/main/classes/fflib_ApexMocksConfig.cls-meta.xml ================================================ 63.0 Active ================================================ FILE: sfdx-source/apex-mocks/main/classes/fflib_ApexMocksUtils.cls ================================================ /** * Copyright (c) 2014-2016, FinancialForce.com, inc * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * - Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * - Neither the name of the FinancialForce.com, inc nor the names of its contributors * may be used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ @NamespaceAccessible public class fflib_ApexMocksUtils { /** * This is taken from https://gist.github.com/afawcett/8dbfc0e1d8c43c982881. * * This method works on the principle that serializing and deserialising child records is supported * * System.assertEquals(1, ((List) * JSON.deserialize( * JSON.serialize( * [select Id, Name, * (select Id, Name from Children__r) from Master__c]), List.class)) * [0].Children__r.size()); * * This method results internally in constructing this JSON, before deserialising it back into SObject's * * [ * { * "attributes": { * "type": "Master__c", * "url": "/services/data/v32.0/sobjects/Master__c/a0YG0000005Jn5uMAC" * }, * "Name": "Fred", * "Id": "a0YG0000005Jn5uMAC", * "Children__r": { * "totalSize": 1, * "done": true, * "records": [ * { * "attributes": { * "type": "Child__c", * "url": "/services/data/v32.0/sobjects/Child__c/a0ZG0000006JGPAMA4" * }, * "Name": "Bob", * "Id": "a0ZG0000006JGPAMA4", * "Master__c": "a0YG0000005Jn5uMAC" * } * ] * } * ] */ public static Object makeRelationship(Type parentsType, List parents, SObjectField relationshipField, List> children) { // Find out more about this relationship... String relationshipFieldName = relationshipField.getDescribe().getName(); DescribeSObjectResult parentDescribe = parents.getSObjectType().getDescribe(); return deserializeParentsAndChildren(parentsType, parentDescribe, relationshipField, parents, children); } /** * Generic overload to makeRelationship. Enables creation of * relationships in a loosely-coupled manner. */ @NamespaceAccessible public static Object makeRelationship( String parentTypeName, String childTypeName, List parents, String relationshipFieldName, List> children) { // Find out more about this relationship... SObjectType parentType = getType(parentTypeName); SObjectField relationshipField = getField(childTypeName, relationshipFieldName); DescribeSObjectResult parentDescribe = parentType.getDescribe(); Type parentsType = List.class; return deserializeParentsAndChildren(parentsType, parentDescribe, relationshipField, parents, children); } /** * Gives the ability to set test values on formula * and other read-only fields of mock SObjects */ @NamespaceAccessible public static Object setReadOnlyFields(SObject objInstance, Type deserializeType, Map properties) { Map fieldNameMap = new Map(); for (SObjectField field : properties.keySet()) { // Resolve the fieldNames from the FieldTokens fieldNameMap.put(field.getDescribe().getName(), properties.get(field)); } return (SObject) setReadOnlyFields(objInstance, deserializeType, fieldNameMap); } /** * Generic overload to setReadOnlyFields. Enables setting test * values on read-only fields by their name */ @NamespaceAccessible public static Object setReadOnlyFields(SObject objInstance, Type deserializeType, Map properties) { Map mergedMap = new Map(objInstance.getPopulatedFieldsAsMap()); // Merge the values from the properties map into the fields already set on the object mergedMap.putAll(properties); // Serialize the merged map, and then deserialize it as the desired object type. String jsonString = JSON.serializePretty(mergedMap); return (SObject) JSON.deserialize(jsonString, deserializeType); } /** * Helper Methods */ private static Object deserializeParentsAndChildren( Type parentsType, DescribeSObjectResult parentDescribe, SObjectField relationshipField, List parents, List> children ) { List childRelationships = parentDescribe.getChildRelationships(); String relationshipName = null; for(Schema.ChildRelationship childRelationship : childRelationships) { if(childRelationship.getField() == relationshipField) { relationshipName = childRelationship.getRelationshipName(); break; } } // Stream the parsed JSON representation of the parent objects back out, injecting children as it goes JSONParser parentsParser = JSON.createParser(JSON.serialize(parents)); JSONParser childrenParser = JSON.createParser(JSON.serialize(children)); JSONGenerator combinedOutput = JSON.createGenerator(false); streamTokens(parentsParser, combinedOutput, new InjectChildrenEventHandler(childrenParser, relationshipName, children) ); // Derserialise back into SObject list complete with children return JSON.deserialize(combinedOutput.getAsString(), parentsType); } /** * Monitors stream events for end of object for each SObject contained in the parent list * then injects the respective childs record list into the stream */ private class InjectChildrenEventHandler implements JSONParserEvents { private JSONParser childrenParser; private String relationshipName; private List> children; private Integer childListIdx = 0; public InjectChildrenEventHandler(JSONParser childrenParser, String relationshipName, List> children) { this.childrenParser = childrenParser; this.relationshipName = relationshipName; this.children = children; this.childrenParser.nextToken(); // Consume the outer array token } public void nextToken(JSONParser fromStream, Integer depth, JSONGenerator toStream) { // Inject children? JSONToken currentToken = fromStream.getCurrentToken(); if(depth == 2 && currentToken == JSONToken.END_OBJECT ) { toStream.writeFieldName(relationshipName); toStream.writeStartObject(); toStream.writeNumberField('totalSize', children[childListIdx].size()); toStream.writeBooleanField('done', true); toStream.writeFieldName('records'); streamTokens(childrenParser, toStream, null); toStream.writeEndObject(); childListIdx++; } } } /** * Utility function to stream tokens from a reader to a write, while providing a basic eventing model */ private static void streamTokens(JSONParser fromStream, JSONGenerator toStream, JSONParserEvents events) { Integer depth = 0; while (fromStream.nextToken() != null) { // Give event handler chance to inject if (events != null) { events.nextToken(fromStream, depth, toStream); } // Forward to output stream switch on fromStream.getCurrentToken() { when START_ARRAY { toStream.writeStartArray(); depth++; } when START_OBJECT { toStream.writeStartObject(); depth++; } when FIELD_NAME { toStream.writeFieldName(fromStream.getCurrentName()); } when VALUE_STRING, VALUE_FALSE, VALUE_TRUE, VALUE_NUMBER_FLOAT, VALUE_NUMBER_INT { toStream.writeString(fromStream.getText()); } when VALUE_NULL { toStream.writeNull(); } when END_OBJECT { toStream.writeEndObject(); depth--; } when END_ARRAY { toStream.writeEndArray(); depth--; } } // Don't continue to stream beyond the initial starting point if (depth == 0) break; } } /** * Basic event used during the above streaming */ private interface JSONParserEvents { void nextToken(JSONParser fromStream, Integer depth, JSONGenerator toStream); } /** * Gets the SObjectType by name */ private static Schema.SObjectType getType(String typeName) { Map gd = Schema.getGlobalDescribe(); SObjectType sobjType = gd.get(typeName); if (sobjType == null) { throw new fflib_ApexMocks.ApexMocksException('SObject type not found: ' + typeName); } return sobjType; } /** * Gets the SObjectField of an object by name */ private static Schema.SObjectField getField(String objectName, String fieldName) { SObjectType sobjType = getType(objectName); Map objectFields = sobjType.getDescribe().fields.getMap(); Schema.SObjectField sobjField = objectFields.get(fieldName); if (sobjField == null) { throw new fflib_ApexMocks.ApexMocksException('SObject field not found: ' + fieldName); } return sobjField; } } ================================================ FILE: sfdx-source/apex-mocks/main/classes/fflib_ApexMocksUtils.cls-meta.xml ================================================ 63.0 ================================================ FILE: sfdx-source/apex-mocks/main/classes/fflib_ArgumentCaptor.cls ================================================ /* * Copyright (c) 2016, FinancialForce.com, inc * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * - Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * - Neither the name of the FinancialForce.com, inc nor the names of its contributors * may be used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * This class implements the capturing framework for ApexMocks * According to Mockito's syntax the type is passed in the capturer construction, * however Apex cannot perform the auto casting that Java can. * To be consistent with Mockito, the capturer does not perform any checks on the type of the argument. * @group Core */ @NamespaceAccessible public with sharing class fflib_ArgumentCaptor { protected List argumentsCaptured = new List(); /** * Factory method to create a new fflib_ArgumentCaptor. * Takes the captured argument's Type for consistency with Mockito syntax. * The Type is IGNORED because we can't determine an object instance's Type at runtime unlike in Java. * Rigorous type checking may be introduced in a future release, so you should specify the expected argument type correctly. * * @param ignoredCaptureType Type (class) of the captured argument * @return A new fflib_ArgumentCaptor. */ @NamespaceAccessible public static fflib_ArgumentCaptor forClass(Type ignoredCaptureType) { return new fflib_ArgumentCaptor(); } /** * Use it to capture the argument. This method must be used inside verification. * Internally, this method registers a special implementation of a Matcher. * This argument matcher stores the argument value so that you can use it later to perform assertions. * * @return a special matcher that matches any argument and remembers the value. */ @NamespaceAccessible public Object capture() { AnyObject myMatcher = new AnyObject(this); return fflib_Match.matches(myMatcher); } /** * Returns the captured value of the argument. When capturing all arguments use getAllValues(). * If verified method was called multiple times then this method returns the latest captured value. * * @return captured argument value. */ @NamespaceAccessible public Object getValue() { if( argumentsCaptured == null || argumentsCaptured.size() == 0) { return null; } //returns the last argument called return argumentsCaptured.get( argumentsCaptured.size() - 1 ); } /** * Returns all captured values. Use it when capturing multiple arguments or when the verified method was called multiple times. * When capturing multiple arguments is called multiple times, this method returns a merged list of all values from all invocations. * * @return Returns all captured values. Use it when capturing multiple arguments on the same call or when the verified method was called multiple times. */ @NamespaceAccessible public List getAllValues() { return argumentsCaptured; } @NamespaceAccessible public class AnyObject implements fflib_IMatcher { private fflib_ArgumentCaptor captor; private Object value; public AnyObject(fflib_ArgumentCaptor captor) { this.captor = captor; } //match with all the possible values and store the arg value public Boolean matches(Object arg) { value = arg; return true; } //store the argument in the list ( this would be called inside the method counter where is compared with the matchers of the method) public void storeArgument() { captor.argumentsCaptured.add(value); } } } ================================================ FILE: sfdx-source/apex-mocks/main/classes/fflib_ArgumentCaptor.cls-meta.xml ================================================ 63.0 Active ================================================ FILE: sfdx-source/apex-mocks/main/classes/fflib_IDGenerator.cls ================================================ /** * Copyright (c) 2014, FinancialForce.com, inc * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * - Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * - Neither the name of the FinancialForce.com, inc nor the names of its contributors * may be used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ @NamespaceAccessible public with sharing class fflib_IDGenerator { private static Integer fakeIdCount = 0; private static final String ID_PATTERN = '000000000000'; /** * Generate a fake Salesforce Id for the given SObjectType */ @NamespaceAccessible public static Id generate(Schema.SObjectType sobjectType) { String keyPrefix = sobjectType.getDescribe().getKeyPrefix(); fakeIdCount++; String fakeIdPrefix = ID_PATTERN.substring(0, ID_PATTERN.length() - String.valueOf(fakeIdCount).length()); return Id.valueOf(keyPrefix + fakeIdPrefix + fakeIdCount); } } ================================================ FILE: sfdx-source/apex-mocks/main/classes/fflib_IDGenerator.cls-meta.xml ================================================ 63.0 ================================================ FILE: sfdx-source/apex-mocks/main/classes/fflib_IMatcher.cls ================================================ /** * Copyright (c) 2014-2016, FinancialForce.com, inc * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * - Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * - Neither the name of the FinancialForce.com, inc nor the names of its contributors * may be used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ @NamespaceAccessible public interface fflib_IMatcher { /** * Whether or not the supplied argument is a match. * Any supplementary information (e.g. boundary conditions, objects to match to etc) * should be cached by the matcher constructor. * @param arg The argument value supplied to the method * @return Boolean True if the argument value is a match, false otherwise. */ Boolean matches(Object arg); } ================================================ FILE: sfdx-source/apex-mocks/main/classes/fflib_IMatcher.cls-meta.xml ================================================ 63.0 ================================================ FILE: sfdx-source/apex-mocks/main/classes/fflib_InOrder.cls ================================================ /* Copyright (c) 2017 FinancialForce.com, inc. All rights reserved. */ /** * @group Core */ @NamespaceAccessible public with sharing class fflib_InOrder extends fflib_MethodVerifier { private final List unorderedMockInstances; private Integer idxMethodCall = 0; private Set notImplementedMethods = new Set { fflib_VerificationMode.ModeName.atMost, fflib_VerificationMode.ModeName.between }; private final fflib_ApexMocks mocks; /** * Construct the InOrder instance. * @param mocks The apex mock object instance. * @param unorderedMockInstances One or more mock implementation classes (listed in any order), whose ordered method calls require verification. */ @NamespaceAccessible public fflib_InOrder(fflib_ApexMocks mocks, List unorderedMockInstances) { this.unorderedMockInstances = unorderedMockInstances; this.mocks = mocks; } /** * Verify a method was called on a mock object. * It performs a no strict ordered verification. * The verification could be either greedy or not depending of the verificationMode passed. * Check the fflib_VerificationMode methods for details. * @param mockInstance The mock object instance. * @param verificationMode Defines the constraints for performing the verification (e.g. the minimum and maximum expected invocation counts). * @return The mock object instance. */ @NamespaceAccessible public Object verify(Object mockInstance, fflib_VerificationMode verificationMode) { mocks.setOrderedVerifier(this); return mocks.verify(mockInstance, verificationMode); } /** * Verify a method was called on a mock object. * It performs the default times(1) verification for the InOrder. * @param mockInstance The mock object instance. * @return The mock object instance. */ @NamespaceAccessible public Object verify(Object mockInstance) { mocks.setOrderedVerifier(this); return mocks.verify(mockInstance); } /** * Verify a method was called on a mock object. * Wrapper for the new syntax call to be conformed to the old style notation * It performs the equivalent of times(times) verification for the InOrder. * @param mockInstance The mock object instance. * @param times The number of times you expect the method to have been called. * @return The mock object instance. */ @NamespaceAccessible public Object verify(Object mockInstance, Integer times) { mocks.setOrderedVerifier(this); return mocks.verify(mockInstance, times); } /** * Verify that after the last successful verified method no more interactions happened on the inOrderMock instance. * @throws Exception with message to help to identify the last method called. */ @NamespaceAccessible public void verifyNoMoreInteractions() { if(idxMethodCall == 0) { verifyNoInteractions(); } if(hasNextInteraction(unorderedMockInstances, idxMethodCall)) { fflib_InvocationOnMock invocation = fflib_MethodCountRecorder.getOrderedMethodCalls().get(idxMethodCall -1); throw new fflib_ApexMocks.ApexMocksException( 'No more Interactions were expected after the ' + invocation.getMethod() +' method.'); } } /** * Verify that no interactions at all happened on the inOrderMock instance. * @throws Exception with message. */ @NamespaceAccessible public void verifyNoInteractions() { if(hasNextInteraction(unorderedMockInstances, 0)) { throw new fflib_ApexMocks.ApexMocksException( 'No Interactions expected on this InOrder Mock instance!'); } } /* * Verifies a method was invoked the expected number of times, with the expected arguments. * The in-order verifier remembers the last method invocation it successfully verified, * and only considers subsequent method invocations for subsequent verifications. * @param qualifiedMethod The method to be verified. * @param expectedArguments The arguments of the method that needs to be verified. * @param verificationMode The verification mode that holds the setting about how the verification should be performed. */ protected override void verify( fflib_QualifiedMethod qm, fflib_MethodArgValues expectedArguments, fflib_VerificationMode verificationMode) { String inOrder = ' in order'; List matchers = fflib_Match.Matching ? fflib_Match.getAndClearMatchers(expectedArguments.argValues.size()) : null; List actualInvocations = fflib_MethodCountRecorder.getOrderedMethodCalls(); List actualArguments = new List(); for (fflib_InvocationOnMock invocation : actualInvocations) { actualArguments.add(invocation.getMethodArgValues()); } if( verificationMode.VerifyMin == 0 && verificationMode.VerifyMax == 0) { Integer methodCounts = countInteractions(matchers, qm, expectedArguments); if(methodCounts != 0 ) throwException(qm, inOrder, fflib_ApexMocks.NEVER, '', methodCounts, verificationMode.CustomAssertMessage, expectedArguments, matchers, actualArguments); } Integer i=0; for ( ; i matchers, fflib_QualifiedMethod qm, fflib_MethodArgValues methodArg) { fflib_InvocationOnMock calledMethod = getNextMethodCall(); while(calledMethod != null) { if(calledMethod.getMethod() == qm && argumentsMatch(calledMethod.getMethodArgValues(), matchers, methodArg)) { //it's our method if (matchers != null) { capture(matchers); } return true; } calledMethod = getNextMethodCall(); } return false; } private Integer countInteractions( List matchers, fflib_QualifiedMethod qualifiedMethod, fflib_MethodArgValues methodArg) { Integer interactionsCouter = 0; for (Integer i = idxMethodCall, len = fflib_MethodCountRecorder.getOrderedMethodCalls().size(); i matchers, fflib_QualifiedMethod qualifiedMethod, fflib_MethodArgValues methodArg) { Integer lastInteracionIndex = 0; //going all through the orderedMethodCalls to find all the interaction of the method for (Integer i = idxMethodCall, len = fflib_MethodCountRecorder.getOrderedMethodCalls().size(); i matchers, fflib_MethodArgValues methodArg) { //Check it was called with the right args. if (matchers != null) { if(fflib_Match.matchesAllArgs(calledMethodArg, matchers)) { //Return now we've matched the method call return true; } } else if(calledMethodArg == methodArg) { //Return now we've matched the method call return true; } return false; } private fflib_InvocationOnMock getNextMethodCall() { return getNextMethodCall(true); } private fflib_InvocationOnMock getNextMethodCall(Boolean updateIdxMethodCall) { Integer idx = 0; for (fflib_InvocationOnMock invocation : fflib_MethodCountRecorder.getOrderedMethodCalls()) { if (idx == idxMethodCall) { if(isForMockInstance(invocation)) { if(updateIdxMethodCall) idxMethodCall++; return invocation; } } else { idx++; } } return null; } private Boolean isForMockInstance(fflib_InvocationOnMock invocation) { for (Object mi : unorderedMockInstances) { if (mi === invocation.getMock()) { return true; } } return false; } /* * Used by the fflib_InOrder invocation verifier to find further interactions with a given mock instances. * @param mockInstances The tracked mock instances - only methods called on these objects are counted as an invocation. * @param idxLastMethodCalled The index of the last matched method, used to offset the search for invocations so we don't double count invocations. * @return Whether or not there were further interactions. */ private Boolean hasNextInteraction(List mockInstances, Integer idxLastMethodCalled) { Integer idx = 0; for (fflib_InvocationOnMock methodCall : fflib_MethodCountRecorder.getOrderedMethodCalls()) { if (isForMockInstance(methodCall)) { idx++; if (idx > idxLastMethodCalled) { return true; } } } return false; } /* * Method that validate the verification mode used in the verify. * Not all the methods from the fflib_VerificationMode are implemented for the different classes that extends the fflib_MethodVerifier. * The error is thrown at run time, so this method is called in the method that actually performs the verify. * @param verificationMode The verification mode that have to been verified. * @throws Exception with message for the fflib_VerificationMode not implemented. */ protected override void validateMode(fflib_VerificationMode verificationMode) { if(notImplementedMethods.contains(verificationMode.Method)) { throw new fflib_ApexMocks.ApexMocksException( 'The ' + verificationMode.Method.name() + ' method is not implemented for the fflib_InOrder class'); } } } ================================================ FILE: sfdx-source/apex-mocks/main/classes/fflib_InOrder.cls-meta.xml ================================================ 63.0 Active ================================================ FILE: sfdx-source/apex-mocks/main/classes/fflib_Inheritor.cls ================================================ /* * Copyright (c) 2016-2017 FinancialForce.com, inc. All rights reserved. */ @isTest @NamespaceAccessible public class fflib_Inheritor implements IA, IB, IC { public interface IA {String doA();} public interface IB {String doB();} public interface IC {String doC();} public String doA(){return 'Did A';} public String doB(){return 'Did B';} public String doC(){return 'Did C';} } ================================================ FILE: sfdx-source/apex-mocks/main/classes/fflib_Inheritor.cls-meta.xml ================================================ 63.0 ================================================ FILE: sfdx-source/apex-mocks/main/classes/fflib_InvocationOnMock.cls ================================================ /* Copyright (c) 2017 FinancialForce.com, inc. All rights reserved. */ /** * An invocation on a mock. * A place holder for mock, the method that was called and the arguments that were passed. * @group Core */ @NamespaceAccessible public with sharing class fflib_InvocationOnMock { private fflib_QualifiedMethod qm; private fflib_MethodArgValues methodArg; private Object mockInstance; /** * Constructor for the class. * @param qm The fflib_QualifiedMethod instance to be stored. * @param args The fflib_MethodArgValues instance to be stored. * @param mockInstance The mock instance to be stored. */ @NamespaceAccessible public fflib_InvocationOnMock(fflib_QualifiedMethod qm, fflib_MethodArgValues args, Object mockInstance) { this.qm = qm; this.methodArg = args; this.mockInstance = mockInstance; } /** * Returns the argument at the given index. * @param index The index of the wanted argument. * @throws ApexMocksException in case the index is out of range. * @return The argument at the given index. */ @NamespaceAccessible public Object getArgument(Integer index) { validateIndex(index); return methodArg.argValues[index]; } /** * Returns the list of arguments passed to the method. * @return The list of arguments. */ @NamespaceAccessible public List getArguments() { return methodArg.argValues; } /** * Returns fflib_MethodArgValues instance that represents the arguments passed to the method. * @return The fflib_MethodArgValues instance that represents the arguments passed to the method. */ @NamespaceAccessible public fflib_MethodArgValues getMethodArgValues() { return methodArg; } /** * Returns the fflib_QualifiedMethod instance that represent the fully qualified method called within the invocation. * @return The method stored in the invocation. */ @NamespaceAccessible public fflib_QualifiedMethod getMethod() { return qm; } /** * Returns the mock object on which the invocation occurs. * @return The mock object on which the invocation occurs. */ @NamespaceAccessible public Object getMock() { return mockInstance; } private void validateIndex(Integer index) { if(index < 0 || index >= methodArg.argValues.size()) { throw new fflib_ApexMocks.ApexMocksException('Invalid index, must be greater or equal to zero and less of ' + methodArg.argValues.size()+'.'); } } } ================================================ FILE: sfdx-source/apex-mocks/main/classes/fflib_InvocationOnMock.cls-meta.xml ================================================ 63.0 Active ================================================ FILE: sfdx-source/apex-mocks/main/classes/fflib_Match.cls ================================================ /** * Copyright (c) 2014, FinancialForce.com, inc * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * - Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * - Neither the name of the FinancialForce.com, inc nor the names of its contributors * may be used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ @NamespaceAccessible public class fflib_Match { private static List matchers = new List(); /** * Matching * True when comparing method arg values to matchers, false when comparing absolute arg values. */ public static Boolean Matching = false; /** * Used internally by the mocking framework, you shouldn't need to call this method directly. * Copies the registered matchers, and then switches matching mode off. * @param expectedSize The expected number of matchers to be returned. If this does not match the actual value an expection is thrown. * @return List The registered matchers, collected while in matching mode. */ @NamespaceAccessible public static List getAndClearMatchers(Integer expectedSize) { Matching = false; List retval = matchers.clone(); matchers.clear(); if (retval.size() != expectedSize) { throw new fflib_ApexMocks.ApexMocksException('The number of matchers defined (' + retval.size() + ').' + ' does not match the number expected (' + expectedSize + ')\n' + 'If you are using matchers all arguments must be passed in as matchers.\n' + 'For example myList.add(fflib_Match.anyInteger(), \'String\') should be defined as myList.add(fflib_Match.anyInteger(), fflib_Match.eq(\'String\')).'); } return retval; } /** * Used internally by the mocking framework, you shouldn't need to call this method directly. * Compares all supplied method arg values to the supplied target matchers. * @param methodArg The arguments supplied when the method was called * @param targetMatchers The matchers the arguments need to be compared with * @throws fflib_ApexMocks.ApexMocksException Thrown when methodArgValues is null/empty, targetMatchers is null, or their sizes don't match * @return Boolean True if all arg values satisfy all of the supplied matchers. */ @NamespaceAccessible public static Boolean matchesAllArgs(fflib_MethodArgValues methodArg, List targetMatchers) { validateArgs(methodArg, targetMatchers); Integer matchersSize = targetMatchers.size(); for (Integer i=0; i targetMatchers) { if (methodArg == null) { throw new fflib_ApexMocks.ApexMocksException('MethodArgs cannot be null'); } if (methodArg.argValues == null) { throw new fflib_ApexMocks.ApexMocksException('MethodArgs.argValues cannot be null'); } if (targetMatchers == null) { throw new fflib_ApexMocks.ApexMocksException('Matchers cannot be null'); } if (targetMatchers.size() != methodArg.argValues.size()) { throw new fflib_ApexMocks.ApexMocksException('MethodArgs and matchers must have the same count' + ', MethodArgs: (' + methodArg.argValues.size() + ') ' + methodArg.argValues + ', Matchers: (' + targetMatchers.size() + ') ' + targetMatchers); } } /** * Registers a matcher which will be stubbed/verified against. * @param matcher The matcher that needs to be compared * @return Object Always returns null. This can then be cast into the correct arg type * so that the right method is called on the mock objects. */ @NamespaceAccessible public static Object matches(fflib_IMatcher matcher) { Matching = true; matchers.add(matcher); return null; } /** * COMBINED MATCHER * The allOf, anyOf and noneOf methods are overloaded to provide fluent matcher calls for up to 4 matcher conditions. * To connect 5 or more, the List version directly. */ /** * Registers a matcher which will check if the method is called with an arg that matches allOf * @param o1 A dummy object returned by registering another matcher * @param o2 A dummy object returned by registering another matcher * @return Object A dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked. (You may need to cast down to your specific object type)public static Object allOf(Object o1, Object o2) */ public static Object allOf(Object o1, Object o2) { return allOf(new Object[]{ o1, o2 }); } /** * Registers a matcher which will check if the method is called with an arg that matches allOf * @param o1 A dummy object returned by registering another matcher * @param o2 A dummy object returned by registering another matcher * @param o3 A dummy object returned by registering another matcher * @return Object A dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked. (You may need to cast down to your specific object type) */ public static Object allOf(Object o1, Object o2, Object o3) { return allOf(new Object[]{ o1, o2, o3 }); } /** * Registers a matcher which will check if the method is called with an arg that matches allOf * @param o1 A dummy object returned by registering another matcher * @param o2 A dummy object returned by registering another matcher * @param o3 A dummy object returned by registering another matcher * @param o4 A dummy object returned by registering another matcher * @return Object A dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked. (You may need to cast down to your specific object type) */ public static Object allOf(Object o1, Object o2, Object o3, Object o4) { return allOf(new Object[]{ o1, o2, o3, o4 }); } /** * Registers a matcher which will check if the method is called with an arg that matches allOf * @param o A list of dummy objects returned by registering other matchers * @return Object A dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked. (You may need to cast down to your specific object type) */ public static Object allOf(List o) { return combined(fflib_MatcherDefinitions.Connective.ALL, o); } /** * Registers a matcher which will check if the method is called with an arg that matches anyOf * @param o1 A dummy object returned by registering another matcher * @param o2 A dummy object returned by registering another matcher * @return Object A dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked. (You may need to cast down to your specific object type) */ public static Object anyOf(Object o1, Object o2) { return anyOf(new Object[]{ o1, o2 }); } /** * Registers a matcher which will check if the method is called with an arg that matches anyOf * @param o1 A dummy object returned by registering another matcher * @param o2 A dummy object returned by registering another matcher * @param o3 A dummy object returned by registering another matcher * @return Object A dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked. (You may need to cast down to your specific object type) */ public static Object anyOf(Object o1, Object o2, Object o3) { return anyOf(new Object[]{ o1, o2, o3 }); } /** * Registers a matcher which will check if the method is called with an arg that matches anyOf * @param o1 A dummy object returned by registering another matcher * @param o2 A dummy object returned by registering another matcher * @param o3 A dummy object returned by registering another matcher * @param o4 A dummy object returned by registering another matcher * @return Object A dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked. (You may need to cast down to your specific object type) */ public static Object anyOf(Object o1, Object o2, Object o3, Object o4) { return anyOf(new Object[]{ o1, o2, o3, o4 }); } /** * Registers a matcher which will check if the method is called with an arg that matches anyOf * @param o A list of dummy objects returned by registering other matchers * @return Object A dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked. (You may need to cast down to your specific object type) */ public static Object anyOf(List o) { return combined(fflib_MatcherDefinitions.Connective.AT_LEAST_ONE, o); } /** * Registers a matcher which will check if the method is called with an arg that matches isNot * @param o1 A dummy object returned by registering another matcher * @return Object A dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked. (You may need to cast down to your specific object type) */ public static Object isNot(Object o1) { return noneOf(new Object[]{ o1 }); } /** * Registers a matcher which will check if the method is called with an arg that matches noneOf * @param o1 A dummy object returned by registering another matcher * @param o2 A dummy object returned by registering another matcher * @return Object A dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked. (You may need to cast down to your specific object type) */ public static Object noneOf(Object o1, Object o2) { return noneOf(new Object[]{ o1, o2 }); } /** * Registers a matcher which will check if the method is called with an arg that matches noneOf * @param o1 A dummy object returned by registering another matcher * @param o2 A dummy object returned by registering another matcher * @param o3 A dummy object returned by registering another matcher * @return Object A dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked. (You may need to cast down to your specific object type) */ public static Object noneOf(Object o1, Object o2, Object o3) { return noneOf(new Object[]{ o1, o2, o3 }); } /** * Registers a matcher which will check if the method is called with an arg that matches noneOf * @param o1 A dummy object returned by registering another matcher * @param o2 A dummy object returned by registering another matcher * @param o3 A dummy object returned by registering another matcher * @param o4 A dummy object returned by registering another matcher * @return Object A dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked. (You may need to cast down to your specific object type) */ public static Object noneOf(Object o1, Object o2, Object o3, Object o4) { return noneOf(new Object[]{ o1, o2, o3, o4 }); } /** * Registers a matcher which will check if the method is called with an arg that matches noneOf * @param o A list of dummy objects returned by registering other matchers * @return Object A dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked. (You may need to cast down to your specific object type) */ public static Object noneOf(List o) { return combined(fflib_MatcherDefinitions.Connective.NONE, o); } private static Object combined(fflib_MatcherDefinitions.Connective connectiveExpression, List o) { return matches(new fflib_MatcherDefinitions.Combined(connectiveExpression, (gatherMatchers(o)))); } private static List gatherMatchers(Object[] ignoredMatcherObjects) { if (ignoredMatcherObjects == null || ignoredMatcherObjects.isEmpty()) { throw new fflib_ApexMocks.ApexMocksException('Must register matchers to combine'); } //Each ignored matcher object represents a matcher that has been registered against fflib_Match.matchers, //but is actually for the connective matchers. List innerMatchers = new List(); Integer innerMatcherCount = ignoredMatcherObjects.size(); while (innerMatchers.size() < innerMatcherCount) { if (matchers.isEmpty()) { throw new fflib_ApexMocks.ApexMocksException('Error reclaiming inner matchers for combined matcher. Wanted ' + innerMatcherCount + ' matchers but only got ' + innerMatchers); } fflib_IMatcher innerMatcher = matchers.remove(matchers.size()-1); //Add to the start of the list to preserve the order in which matchers were declared. //Note. Apex throws list index out of bounds if inserting an element into an empty list at index 0S if (!innerMatchers.isEmpty()) { innerMatchers.add(0, innerMatcher); } else { innerMatchers.add(innerMatcher); } } return innerMatchers; } /** * ALL OTHER MATCHER METHODS */ /** * Registers a matcher which will check if the method is called with an arg that matches eq * @param toMatch The Object to be compared * @return Object A dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked. (You may need to cast down to your specific object type) */ public static Object eq(Object toMatch) { return matches(new fflib_MatcherDefinitions.Eq(toMatch)); } /** * Registers a matcher which will check if the method is called with an arg that matches eqBoolean * @param toMatch The Boolean to be compared * @return Boolean A dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked. */ public static Boolean eqBoolean(Boolean toMatch) { return (Boolean)matches(new fflib_MatcherDefinitions.Eq(toMatch)); } /** * Registers a matcher which will check if the method is called with an arg that matches eqDate * @param toMatch The Date to be compared * @return Date A dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked. */ public static Date eqDate(Date toMatch) { return (Date)matches(new fflib_MatcherDefinitions.Eq(toMatch)); } /** * Registers a matcher which will check if the method is called with an arg that matches eqDatetime * @param toMatch The Datetime to be compared * @return Datetime A dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked. */ public static Datetime eqDatetime(Datetime toMatch) { return (Datetime)matches(new fflib_MatcherDefinitions.Eq(toMatch)); } /** * Registers a matcher which will check if the method is called with an arg that matches eqDecimal * @param toMatch The Decimal to be compared * @return Decimal A dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked. */ public static Decimal eqDecimal(Decimal toMatch) { return (Decimal)matches(new fflib_MatcherDefinitions.Eq(toMatch)); } /** * Registers a matcher which will check if the method is called with an arg that matches eqDouble * @param toMatch The Double to be compared * @return Double A dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked. */ public static Double eqDouble(Double toMatch) { return (Double)matches(new fflib_MatcherDefinitions.Eq(toMatch)); } /** * Registers a matcher which will check if the method is called with an arg that matches eqId * @param toMatch The Id to be compared * @return Id A dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked. */ public static Id eqId(Id toMatch) { return (Id)matches(new fflib_MatcherDefinitions.Eq(toMatch)); } /** * Registers a matcher which will check if the method is called with an arg that matches eqInteger * @param toMatch The Integer to be compared * @return Integer A dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked. */ public static Integer eqInteger(Integer toMatch) { return (Integer)matches(new fflib_MatcherDefinitions.Eq(toMatch)); } /** * Registers a matcher which will check if the method is called with an arg that matches eqList * @param toMatch The List to be compared * @return List A dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked. */ public static List eqList(List toMatch) { return (List)matches(new fflib_MatcherDefinitions.Eq(toMatch)); } /** * Registers a matcher which will check if the method is called with an arg that matches eqLong * @param toMatch The Long to be compared * @return Long A dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked. */ public static Long eqLong(Long toMatch) { return (Long)matches(new fflib_MatcherDefinitions.Eq(toMatch)); } /** * Registers a matcher which will check if the method is called with an arg that matches eqSObjectField * @param toMatch The SObjectField to be compared * @return SObjectField A dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked. */ public static SObjectField eqSObjectField(SObjectField toMatch) { return (SObjectField)matches(new fflib_MatcherDefinitions.Eq(toMatch)); } /** * Registers a matcher which will check if the method is called with an arg that matches eqSObjectType * @param toMatch The SObjectType to be compared * @return SObjectType A dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked. */ public static SObjectType eqSObjectType(SObjectType toMatch) { return (SObjectType)matches(new fflib_MatcherDefinitions.Eq(toMatch)); } /** * Registers a matcher which will check if the method is called with an arg that matches eqString * @param toMatch The String to be compared * @return String A dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked. */ public static String eqString(String toMatch) { return (String)matches(new fflib_MatcherDefinitions.Eq(toMatch)); } /** * Registers a matcher which will check if the method is called with an arg that matches refEq * @param toMatch The Object to be compared * @return Object A dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked. (You may need to cast down to your specific object type) */ public static Object refEq(Object toMatch) { return matches(new fflib_MatcherDefinitions.RefEq(toMatch)); } /** * Registers a matcher which will check if the method is called with an arg that matches anyBoolean * @return Boolean A dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked. */ public static Boolean anyBoolean() { return (Boolean)matches(new fflib_MatcherDefinitions.AnyBoolean()); } /** * Registers a matcher which will check if the method is called with an arg that matches anyDate * @return Date A dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked. */ public static Date anyDate() { return (Date)matches(new fflib_MatcherDefinitions.AnyDate()); } /** * Registers a matcher which will check if the method is called with an arg that matches anyDatetime * @return Datetime A dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked. */ public static Datetime anyDatetime() { return (Datetime)matches(new fflib_MatcherDefinitions.AnyDatetime()); } /** * Registers a matcher which will check if the method is called with an arg that matches anyDecimal * @return Decimal A dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked. */ public static Decimal anyDecimal() { return (Decimal)matches(new fflib_MatcherDefinitions.AnyDecimal()); } /** * Registers a matcher which will check if the method is called with an arg that matches anyDouble * @return Double A dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked. */ public static Double anyDouble() { return (Double)matches(new fflib_MatcherDefinitions.AnyDouble()); } /** * Registers a matcher which will check if the method is called with an arg that matches anyFieldSet * @return Schema.FieldSet A dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked. */ public static Schema.FieldSet anyFieldSet() { return (Schema.FieldSet)matches(new fflib_MatcherDefinitions.AnyFieldSet()); } /** * Registers a matcher which will check if the method is called with an arg that matches anyId * @return Id A dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked. */ public static Id anyId() { return (Id)matches(new fflib_MatcherDefinitions.AnyId()); } /** * Registers a matcher which will check if the method is called with an arg that matches anyInteger * @return Integer A dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked. */ public static Integer anyInteger() { return (Integer)matches(new fflib_MatcherDefinitions.AnyInteger()); } /** * Registers a matcher which will check if the method is called with an arg that matches anyList * @return List A dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked. */ public static List anyList() { return (List)matches(new fflib_MatcherDefinitions.AnyList()); } /** * Registers a matcher which will check if the method is called with an arg that matches anyLong * @return Long A dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked. */ public static Long anyLong() { return (Long)matches(new fflib_MatcherDefinitions.AnyLong()); } /** * Registers a matcher which will check if the method is called with an arg that matches anyObject * @return Object A dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked. (You may need to cast down to your specific object type) */ public static Object anyObject() { return matches(new fflib_MatcherDefinitions.AnyObject()); } /** * Registers a matcher which will check if the method is called with an arg that matches anyString * @return String A dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked. */ public static String anyString() { return (String)matches(new fflib_MatcherDefinitions.AnyString()); } /** * Registers a matcher which will check if the method is called with an arg that matches anySObject * @return SObject A dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked. */ public static SObject anySObject() { return (SObject)matches(new fflib_MatcherDefinitions.AnySObject()); } /** * Registers a matcher which will check if the method is called with an arg that matches anySObjectField * @return SObjectField A dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked. */ public static SObjectField anySObjectField() { return (SObjectField)matches(new fflib_MatcherDefinitions.AnySObjectField()); } /** * Registers a matcher which will check if the method is called with an arg that matches anySObjectType * @return SObjectType A dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked. */ public static SObjectType anySObjectType() { return (SObjectType)matches(new fflib_MatcherDefinitions.AnySObjectType()); } /** * Registers a matcher which will check if the method is called with an arg that matches dateAfter (not inclusive) * @param fromDate The Date to be compared * @return Date A dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked. */ public static Date dateAfter(Date fromDate) { return dateAfter(fromDate, false); } /** * Registers a matcher which will check if the method is called with an arg that matches dateAfter * @param fromDate The Date to be compared * @param inclusive Whether or not a Date equal to fromDate should be considered a match * @return Date A dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked. */ public static Date dateAfter(Date fromDate, Boolean inclusive) { return (Date)matches(new fflib_MatcherDefinitions.DatetimeAfter(fromDate, inclusive)); } /** * Registers a matcher which will check if the method is called with an arg that matches dateBefore (not inclusive) * @param toDate The Date to be compared * @return Date A dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked. */ public static Date dateBefore(Date toDate) { return dateBefore(toDate, false); } /** * Registers a matcher which will check if the method is called with an arg that matches dateBefore * @param toDate The Date to be compared * @param inclusive Whether or not a Date equal to toDate should be considered a match * @return Date A dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked. */ public static Date dateBefore(Date toDate, Boolean inclusive) { return (Date)matches(new fflib_MatcherDefinitions.DatetimeBefore(toDate, inclusive)); } /** * Registers a matcher which will check if the method is called with an arg that matches dateBetween (not inclusive) * @param fromDate The lower bound Date to be compared * @param toDate The upper bound Date to be compared * @return Date A dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked. */ public static Date dateBetween(Date fromDate, Date toDate) { return dateBetween(fromDate, false, toDate, false); } /** * Registers a matcher which will check if the method is called with an arg that matches dateBetween * @param fromDate The lower bound Date to be compared * @param inclusiveFrom Whether or not a Date equal to fromDate should be considered a match * @param toDate The upper bound Date to be compared * @param inclusiveTo Whether or not a Date equal to toDate should be considered a match * @return Date A dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked. */ public static Date dateBetween(Date fromDate, Boolean inclusiveFrom, Date toDate, Boolean inclusiveTo) { return (Date)matches(new fflib_MatcherDefinitions.DatetimeBetween(fromDate, inclusiveFrom, toDate, inclusiveTo)); } /** * Registers a matcher which will check if the method is called with an arg that matches datetimeAfter (not inclusive) * @param fromDate The Datetime to be compared * @return Datetime A dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked. */ public static Datetime datetimeAfter(Datetime fromDate) { return datetimeAfter(fromDate, false); } /** * Registers a matcher which will check if the method is called with an arg that matches datetimeAfter * @param fromDate The Datetime to be compared * @param inclusive Whether or not a Datetime equal to fromDate should be considered a match * @return Datetime A dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked. */ public static Datetime datetimeAfter(Datetime fromDate, Boolean inclusive) { return (Datetime)matches(new fflib_MatcherDefinitions.DatetimeAfter(fromDate, inclusive)); } /** * Registers a matcher which will check if the method is called with an arg that matches datetimeBefore (not inclusive) * @param toDate The Datetime to be compared * @return Datetime A dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked. */ public static Datetime datetimeBefore(Datetime toDate) { return datetimeBefore(toDate, false); } /** * Registers a matcher which will check if the method is called with an arg that matches datetimeBefore * @param toDate The Datetime to be compared * @param inclusive Whether or not a Datetime equal to toDate should be considered a match * @return Datetime A dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked. */ public static Datetime datetimeBefore(Datetime toDate, Boolean inclusive) { return (Datetime)matches(new fflib_MatcherDefinitions.DatetimeBefore(toDate, inclusive)); } /** * Registers a matcher which will check if the method is called with an arg that matches datetimeBetween (not inclusive) * @param fromDate The lower bound Datetime to be compared * @param toDate The upper bound Datetime to be compared * @return Datetime A dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked. */ public static Datetime datetimeBetween(Datetime fromDate, Datetime toDate) { return datetimeBetween(fromDate, false, toDate, false); } /** * Registers a matcher which will check if the method is called with an arg that matches datetimeBetween * @param fromDate The lower bound Datetime to be compared * @param inclusiveFrom Whether or not a Datetime equal to fromDate should be considered a match * @param toDate The upper bound Datetime to be compared * @param inclusiveTo Whether or not a Datetime equal to toDate should be considered a match * @return Datetime A dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked. */ public static Datetime datetimeBetween(Datetime fromDate, Boolean inclusiveFrom, Datetime toDate, Boolean inclusiveTo) { return (Datetime)matches(new fflib_MatcherDefinitions.DatetimeBetween(fromDate, inclusiveFrom, toDate, inclusiveTo)); } /** * Registers a matcher which will check if the method is called with an arg that matches decimalBetween (not inclusive) * @param lower The lower number to be compared * @param upper The upper number to be compared * @return Decimal A dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked. */ public static Decimal decimalBetween(Decimal lower, Decimal upper) { return decimalBetween(lower, false, upper, false); } /** * Registers a matcher which will check if the method is called with an arg that matches decimalBetween * @param lower The lower number to be compared * @param inclusiveLower Whether or not a number equal to the lower bound should be considered a match * @param upper The upper number to be compared * @param inclusiveUpper Whether or not a number equal to the upper bound should be considered a match * @return Decimal A dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked. */ public static Decimal decimalBetween(Decimal lower, Boolean inclusiveLower, Decimal upper, Boolean inclusiveUpper) { return (Decimal)matches(new fflib_MatcherDefinitions.DecimalBetween(lower, inclusiveLower, upper, inclusiveUpper)); } /** * Registers a matcher which will check if the method is called with an arg that matches decimalLessThan (not inclusive) * @param toMatch The number to be compared * @return Decimal A dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked. */ public static Decimal decimalLessThan(Decimal toMatch) { return decimalLessThan(toMatch, false); } /** * Registers a matcher which will check if the method is called with an arg that matches decimalLessThan * @param toMatch The number to be compared * @param inclusive Whether or not a number equal to toMatch should be considered a match * @return Decimal A dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked. */ public static Decimal decimalLessThan(Decimal toMatch, Boolean inclusive) { return (Decimal)matches(new fflib_MatcherDefinitions.DecimalLessThan(toMatch, inclusive)); } /** * Registers a matcher which will check if the method is called with an arg that matches decimalMoreThan (not inclusive) * @param toMatch The number to be compared * @return Decimal A dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked. */ public static Decimal decimalMoreThan(Decimal toMatch) { return decimalMoreThan(toMatch, false); } /** * Registers a matcher which will check if the method is called with an arg that matches decimalMoreThan * @param toMatch The number to be compared * @param inclusive Whether or not a number equal to toMatch should be considered a match * @return Decimal A dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked. */ public static Decimal decimalMoreThan(Decimal toMatch, Boolean inclusive) { return (Decimal)matches(new fflib_MatcherDefinitions.DecimalMoreThan(toMatch, inclusive)); } /** * Registers a matcher which will check if the method is called with an arg that matches doubleBetween (not inclusive) * @param lower The lower number to be compared * @param upper The upper number to be compared * @return Double A dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked. */ public static Double doubleBetween(Double lower, Double upper) { return doubleBetween(lower, false, upper, false); } /** * Registers a matcher which will check if the method is called with an arg that matches doubleBetween * @param lower The lower number to be compared * @param inclusiveLower Whether or not a number equal to the lower bound should be considered a match * @param upper The upper number to be compared * @param inclusiveUpper Whether or not a number equal to the upper bound should be considered a match * @return Double A dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked. */ public static Double doubleBetween(Double lower, Boolean inclusiveLower, Double upper, Boolean inclusiveUpper) { return (Double)matches(new fflib_MatcherDefinitions.DecimalBetween(lower, inclusiveLower, upper, inclusiveUpper)); } /** * Registers a matcher which will check if the method is called with an arg that matches doubleLessThan (not inclusive) * @param toMatch The number to be compared * @return Double A dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked. */ public static Double doubleLessThan(Double toMatch) { return doubleLessThan(toMatch, false); } /** * Registers a matcher which will check if the method is called with an arg that matches doubleLessThan * @param toMatch The number to be compared * @param inclusive Whether or not a number equal to toMatch should be considered a match * @return Double A dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked. */ public static Double doubleLessThan(Double toMatch, Boolean inclusive) { return (Double)matches(new fflib_MatcherDefinitions.DecimalLessThan(toMatch, inclusive)); } /** * Registers a matcher which will check if the method is called with an arg that matches doubleMoreThan (not inclusive) * @param toMatch The number to be compared * @return Double A dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked. */ public static Double doubleMoreThan(Double toMatch) { return doubleMoreThan(toMatch, false); } /** * Registers a matcher which will check if the method is called with an arg that matches doubleMoreThan * @param toMatch The number to be compared * @param inclusive Whether or not a number equal to toMatch should be considered a match * @return Double A dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked. */ public static Double doubleMoreThan(Double toMatch, Boolean inclusive) { return (Double)matches(new fflib_MatcherDefinitions.DecimalMoreThan(toMatch, inclusive)); } /** * Registers a matcher which will check if the method is called with an arg that matches FieldSetEquivalentTo * @param toMatch The fieldSet to be compared * @return Schema.FieldSet A dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked. */ public static Schema.FieldSet fieldSetEquivalentTo(Schema.FieldSet toMatch) { return (Schema.FieldSet)matches(new fflib_MatcherDefinitions.FieldSetEquivalentTo(toMatch)); } /** * Registers a matcher which will check if the method is called with an arg that matches integerBetween (not inclusive) * @param lower The lower number to be compared * @param upper The upper number to be compared * @return Integer A dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked. */ public static Integer integerBetween(Integer lower, Integer upper) { return integerBetween(lower, false, upper, false); } /** * Registers a matcher which will check if the method is called with an arg that matches integerBetween * @param lower The lower number to be compared * @param inclusiveLower Whether or not a number equal to the lower bound should be considered a match * @param upper The upper number to be compared * @param inclusiveUpper Whether or not a number equal to the upper bound should be considered a match * @return Integer A dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked. */ public static Integer integerBetween(Integer lower, Boolean inclusiveLower, Integer upper, Boolean inclusiveUpper) { return (Integer)matches(new fflib_MatcherDefinitions.DecimalBetween(lower, inclusiveLower, upper, inclusiveUpper)); } /** * Registers a matcher which will check if the method is called with an arg that matches integerLessThan (not inclusive) * @param toMatch The number to be compared * @return Integer A dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked. */ public static Integer integerLessThan(Integer toMatch) { return integerLessThan(toMatch, false); } /** * Registers a matcher which will check if the method is called with an arg that matches integerLessThan * @param toMatch The number to be compared * @param inclusive Whether or not a number equal to toMatch should be considered a match * @return Integer A dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked. */ public static Integer integerLessThan(Integer toMatch, Boolean inclusive) { return (Integer)matches(new fflib_MatcherDefinitions.DecimalLessThan(toMatch, inclusive)); } /** * Registers a matcher which will check if the method is called with an arg that matches integerMoreThan (not inclusive) * @param toMatch The number to be compared * @return Integer A dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked. */ public static Integer integerMoreThan(Integer toMatch) { return integerMoreThan(toMatch, false); } /** * Registers a matcher which will check if the method is called with an arg that matches integerMoreThan * @param toMatch The number to be compared * @param inclusive Whether or not a number equal to toMatch should be considered a match * @return Integer A dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked. */ public static Integer integerMoreThan(Integer toMatch, Boolean inclusive) { return (Integer)matches(new fflib_MatcherDefinitions.DecimalMoreThan(toMatch, inclusive)); } /** * Registers a matcher which will check if the method is called with an arg that matches isNotNull * @return Object A dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked. (You may need to cast down to your specific object type) */ public static Object isNotNull() { return matches(new fflib_MatcherDefinitions.IsNotNull()); } /** * Registers a matcher which will check if the method is called with an arg that matches isNull * @return Object A dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked. (You may need to cast down to your specific object type) */ public static Object isNull() { return matches(new fflib_MatcherDefinitions.IsNull()); } /** * Registers a matcher which will check if the method is called with an arg that matches listContains * @param toMatch The list to be compared * @return Object A dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked. (You may need to cast down to your specific object type) */ public static Object listContains(Object toMatch) { return matches(new fflib_MatcherDefinitions.ListContains(toMatch)); } /** * Registers a matcher which will check if the method is called with an arg that matches listIsEmpty * @return Object A dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked. (You may need to cast down to your specific object type) */ public static Object listIsEmpty() { return matches(new fflib_MatcherDefinitions.ListIsEmpty()); } /** * Registers a matcher which will check if the method is called with an arg that matches longBetween (not inclusive) * @param lower The lower number to be compared * @param upper The upper number to be compared * @return Long A dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked. */ public static Long longBetween(Long lower, Long upper) { return longBetween(lower, false, upper, false); } /** * Registers a matcher which will check if the method is called with an arg that matches longBetween * @param lower The lower number to be compared * @param inclusiveLower Whether or not a number equal to the lower bound should be considered a match * @param upper The upper number to be compared * @param inclusiveUpper Whether or not a number equal to the upper bound should be considered a match * @return Long A dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked. */ public static Long longBetween(Long lower, Boolean inclusiveLower, Long upper, Boolean inclusiveUpper) { return (Long)matches(new fflib_MatcherDefinitions.DecimalBetween(lower, inclusiveLower, upper, inclusiveUpper)); } /** * Registers a matcher which will check if the method is called with an arg that matches longLessThan (not inclusive) * @param toMatch The number to be compared * @return Long A dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked. */ public static Long longLessThan(Long toMatch) { return longLessThan(toMatch, false); } /** * Registers a matcher which will check if the method is called with an arg that matches longLessThan * @param toMatch The number to be compared * @param inclusive Whether or not a number equal to toMatch should be considered a match * @return Long A dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked. */ public static Long longLessThan(Long toMatch, Boolean inclusive) { return (Long)matches(new fflib_MatcherDefinitions.DecimalLessThan(toMatch, inclusive)); } /** * Registers a matcher which will check if the method is called with an arg that matches longMoreThan (not inclusive) * @param toMatch The number to be compared * @return Long A dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked. */ public static Long longMoreThan(Long toMatch) { return longMoreThan(toMatch, false); } /** * Registers a matcher which will check if the method is called with an arg that matches longMoreThan * @param toMatch The number to be compared * @param inclusive Whether or not a number equal to toMatch should be considered a match * @return Long A dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked. */ public static Long longMoreThan(Long toMatch, Boolean inclusive) { return (Long)matches(new fflib_MatcherDefinitions.DecimalMoreThan(toMatch, inclusive)); } /** * Registers a matcher which will check if the method is called with an SObject of specified SObjectType * @param objectType The SObjectType to be compared * @return SObject a dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked */ public static SObject sObjectOfType(Schema.SObjectType objectType) { return (SObject)matches(new fflib_MatcherDefinitions.SObjectOfType(objectType)); } /** * Registers a matcher which will check if the method is called with an SObject * @param toMatch A Map of SObjectFields to required values, to be compared to concrete SObject records * @return SObject a dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked */ public static SObject sObjectWith(Map toMatch) { return (SObject)matches(new fflib_MatcherDefinitions.SObjectWith(toMatch)); } /** * Registers a matcher which will check if the method is called with a list of SObject * @param toMatch A list of Map of SObjectFields to required values, to be compared to concrete SObject records * @return SObject a dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked */ public static SObject[] sObjectsWith(list> toMatch) { return (SObject[])matches(new fflib_MatcherDefinitions.SObjectsWith(toMatch,true)); } /** * Registers a matcher which will check if the method is called with a list of SObject * @param toMatch A list of Map of SObjectFields to required values, to be compared to concrete SObject records. Comparison can be order dependent * @return SObject a dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked */ public static SObject[] sObjectsWith(list> toMatch, Boolean matchInOrder) { return (SObject[])matches(new fflib_MatcherDefinitions.SObjectsWith(toMatch,matchInOrder)); } /** * Registers a matcher which will check if the method is called with an SObject * @param toMatch The Id to be compared * @return SObject a dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked */ public static SObject sObjectWithId(Id toMatch) { return (SObject)matches(new fflib_MatcherDefinitions.SObjectWithId(toMatch)); } /** * Registers a matcher which will check if the method is called with an SObject * @param toMatch The name to be compared * @return SObject a dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked */ public static SObject sObjectWithName(String toMatch) { return (SObject)matches(new fflib_MatcherDefinitions.SObjectWithName(toMatch)); } /** * Registers a matcher which will check if the method is called with an arg that matches stringContains * @param toMatch The substring to be compared * @return String A dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked. */ public static String stringContains(String toMatch) { return (String)matches(new fflib_MatcherDefinitions.StringContains(toMatch)); } /** * Registers a matcher which will check if the method is called with an arg that matches stringEndsWith * @param toMatch The substring to be compared * @return String A dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked. */ public static String stringEndsWith(String toMatch) { return (String)matches(new fflib_MatcherDefinitions.StringEndsWith(toMatch)); } /** * Registers a matcher which will check if the method is called with an arg that matches stringIsBlank * @return String A dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked. */ public static String stringIsBlank() { return (String)matches(new fflib_MatcherDefinitions.StringIsBlank()); } /** * Registers a matcher which will check if the method is called with an arg that matches stringIsNotBlank * @return String A dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked. */ public static String stringIsNotBlank() { return (String)matches(new fflib_MatcherDefinitions.StringIsNotBlank()); } /** * Registers a matcher which will check if the method is called with an arg that matches stringMatches * @param regEx The regex String to be compared * @return String A dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked. */ public static String stringMatches(String regEx) { return (String)matches(new fflib_MatcherDefinitions.StringMatches(regEx)); } /** * Registers a matcher which will check if the method is called with an arg that matches stringStartsWith * @param toMatch The substring to be compared * @return String A dummy object of the correct type, so that when called inline as part of a method call, the correct method is invoked. */ public static String stringStartsWith(String toMatch) { return (String)matches(new fflib_MatcherDefinitions.StringStartsWith(toMatch)); } } ================================================ FILE: sfdx-source/apex-mocks/main/classes/fflib_Match.cls-meta.xml ================================================ 63.0 ================================================ FILE: sfdx-source/apex-mocks/main/classes/fflib_MatcherDefinitions.cls ================================================ /** * Copyright (c) 2014-2017, FinancialForce.com, inc * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * - Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * - Neither the name of the FinancialForce.com, inc nor the names of its contributors * may be used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * Class providing Apex Mocks standard matcher implementations. * You shouldn't need to reference the classes directly outside of the ApexMocks framework, instead use the equivalent helper method in fflib_Match * to construct the matcher, register the matcher and return an object of the correct type to be called in your unit test. * E.g. Don't construct Eq(Object toMatch), instead call fflib_Match.eq(Object toMatch). */ @NamespaceAccessible public with sharing class fflib_MatcherDefinitions { /** * Connective - Enum representing the possible operators for the Combined matcher. Possible values: ALL, AT_LEAST_ONE, NONE */ public Enum Connective { ALL, AT_LEAST_ONE, NONE } /* * COMBINED MATCHER */ /** * Combined matcher: compares the supplied argument matches one, all or none of the internal matchers */ @NamespaceAccessible public class Combined implements fflib_IMatcher { private Connective connectiveExpression; private List internalMatchers; /** * Combined constructor * @param connectiveExpression Controls the combination mode, i.e. if we need to match all, any or none of the inner matchers * @param internalMatchers An ordered list of the internal matchers to be combined * @return fflib_MatcherDefinitions.Combined A new Combined instance */ public Combined(Connective connectiveExpression, List internalMatchers) { this.connectiveExpression = validate(connectiveExpression); this.internalMatchers = validate(internalMatchers); } public Boolean matches(Object arg) { for (fflib_IMatcher internalMatcher : internalMatchers) { if (internalMatcher.matches(arg)) { if (connectiveExpression == Connective.AT_LEAST_ONE) { //At least one match => success! return true; } else if (connectiveExpression == Connective.NONE) { //At least one match => failure! return false; } } else if (connectiveExpression == Connective.ALL) { //At least one mismatch => failure! return false; } } //We didn't return early. //If matching any, must have been no matches => failure! //If matching all, must have been all matches => success! //If matching none, must have been all mismatches => success! return connectiveExpression != Connective.AT_LEAST_ONE; } private Connective validate(Connective connectiveExpression) { if (connectiveExpression == null) { throw new fflib_ApexMocks.ApexMocksException('Invalid connective expression: ' + connectiveExpression); } return connectiveExpression; } private List validate(List innerMatchers) { if (innerMatchers == null || innerMatchers.isEmpty()) { throw new fflib_ApexMocks.ApexMocksException('Invalid inner matchers: ' + innerMatchers); } return innerMatchers; } public override String toString() { List internalDescriptions = new List(); for (fflib_IMatcher internalMatcher : internalMatchers) { internalDescriptions.add('' + internalMatcher); } String internalDescription = String.join(internalDescriptions, ', '); switch on connectiveExpression { when AT_LEAST_ONE { return '[any of: ' + internalDescription + ']'; } when ALL { return '[all of: ' + internalDescription + ']'; } when else { return '[none of: ' + internalDescription + ']'; } } } } /* * OBJECT MATCHERS */ /** * Eq matcher: checks if the supplied argument is equal (==) to a specified object */ @NamespaceAccessible public class Eq implements fflib_IMatcher { private Object toMatch; /** * Eq constructor * @param toMatch The object to be compared * @return fflib_MatcherDefinitions.Eq A new Eq instance */ public Eq(Object toMatch) { this.toMatch = validateNotNull(toMatch); } public Boolean matches(Object arg) { return toMatch == arg; } public override String toString() { return '[equals ' + stringify(toMatch) + ']'; } } /** * RefEq matcher: checks if the supplied argument is a reference to the same object (===) as a specified object */ @NamespaceAccessible public class RefEq implements fflib_IMatcher { private Object toMatch; /** * RefEq constructor * @param toMatch The object to be compared * @return fflib_MatcherDefinitions.RefEq A new RefEq instance */ public RefEq(Object toMatch) { this.toMatch = validateNotNull(toMatch); } public Boolean matches(Object arg) { return toMatch === arg; } public override String toString() { return '[reference equals ' + fflib_MatcherDefinitions.stringify(toMatch) + ']'; } } /* * ANY MATCHERS */ /** * AnyBoolean matcher: checks if the supplied argument is an instance of a Boolean */ @NamespaceAccessible public class AnyBoolean implements fflib_IMatcher { public Boolean matches(Object arg) { return arg != null && arg instanceof Boolean; } public override String toString() { return '[any Boolean]'; } } /** * AnyDate matcher: checks if the supplied argument is an instance of a Date */ @NamespaceAccessible public class AnyDate implements fflib_IMatcher { public Boolean matches(Object arg) { return arg != null && arg instanceof Date; } public override String toString() { return '[any Date]'; } } /** * AnyDatetime matcher: checks if the supplied argument is an instance of a Datetime @NamespaceAccessible */ public class AnyDatetime implements fflib_IMatcher { public Boolean matches(Object arg) { return arg != null && arg instanceof Datetime; } public override String toString() { return '[any DateTime]'; } } /** @NamespaceAccessible * AnyDecimal matcher: checks if the supplied argument is an instance of a Decimal */ public class AnyDecimal implements fflib_IMatcher { public Boolean matches(Object arg) { return arg != null && arg instanceof Decimal; } public override String toString() { return '[any Decimal]'; } } /** * AnyDouble matcher: checks if the supplied argument is an instance of a Double */ @NamespaceAccessible public class AnyDouble implements fflib_IMatcher { public Boolean matches(Object arg) { return arg != null && arg instanceof Double; } public override String toString() { return '[any Double]'; } } /** * AnyFieldSet matcher: checks if the supplied argument is an instance of a FieldSet */ @NamespaceAccessible public class AnyFieldSet implements fflib_IMatcher { public Boolean matches(Object arg) { return arg != null && arg instanceof Schema.FieldSet; } public override String toString() { return '[any FieldSet]'; } } /** * AnyId matcher: checks if the supplied argument is an instance of an Id @NamespaceAccessible */ public class AnyId implements fflib_IMatcher { public Boolean matches(Object arg) { return arg != null && arg instanceof Id; } public override String toString() { return '[any Id]'; } } /** @NamespaceAccessible * AnyInteger matcher: checks if the supplied argument is an instance of an Integer */ public class AnyInteger implements fflib_IMatcher { public Boolean matches(Object arg) { return arg != null && arg instanceof Integer; } public override String toString() { return '[any Integer]'; } } /** * AnyList matcher: checks if the supplied argument is an instance of a List */ @NamespaceAccessible public class AnyList implements fflib_IMatcher { public Boolean matches(Object arg) { return arg != null && arg instanceof List; } public override String toString() { return '[any list]'; } } /** * AnyLong matcher: checks if the supplied argument is an instance of a Long */ @NamespaceAccessible public class AnyLong implements fflib_IMatcher { public Boolean matches(Object arg) { return arg != null && arg instanceof Long; } public override String toString() { return '[any Long]'; } } /** * AnyObject matcher: checks if the supplied argument is an instance of an Object */ public class AnyObject implements fflib_IMatcher { public Boolean matches(Object arg) { return arg != null; } public override String toString() { return '[any Object]'; } } /** * AnyString matcher: checks if the supplied argument is an instance of a String */ @NamespaceAccessible public class AnyString implements fflib_IMatcher { public Boolean matches(Object arg) { return arg != null && arg instanceof String; } public override String toString() { return '[any String]'; } } /** * AnySObject matcher: checks if the supplied argument is an instance of an SObject */ @NamespaceAccessible public class AnySObject implements fflib_IMatcher { public Boolean matches(Object arg) { return arg != null && arg instanceof SObject; } public override String toString() { return '[any SObject]'; } } /** * AnySObjectField matcher: checks if the supplied argument is an instance of an SObjectField */ @NamespaceAccessible public class AnySObjectField implements fflib_IMatcher { public Boolean matches(Object arg) { return arg != null && arg instanceof SObjectField; } public override String toString() { return '[any SObjectField]'; } } /** * AnySObjectType matcher: checks if the supplied argument is an instance of an SObjectType @NamespaceAccessible */ public class AnySObjectType implements fflib_IMatcher { public Boolean matches(Object arg) { return arg != null && arg instanceof SObjectType; } public override String toString() { return '[any SObjectType]'; } } /* * DATETIME MATCHERS */ /** * DatetimeAfter matcher: checks if the supplied argument is after a specified datetime */ @NamespaceAccessible public class DatetimeAfter implements fflib_IMatcher { private Datetime fromDatetime; private Boolean inclusive; /** * DatetimeAfter constructor * @param fromDatetime The datetime to be compared * @param inclusive Whether or not dates equal to the fromDatetime should be considered a match * @return fflib_MatcherDefinitions.DatetimeAfter A new DatetimeAfter instance */ public DatetimeAfter(Datetime fromDatetime, Boolean inclusive) { this.fromDatetime = (Datetime)validateNotNull(fromDatetime); this.inclusive = (Boolean)validateNotNull(inclusive); } public Boolean matches(Object arg) { if (arg instanceof Datetime) { Datetime datetimeToCompare = (Datetime)arg; return inclusive ? fromDatetime <= datetimeToCompare : fromDatetime < datetimeToCompare; } return false; } public override String toString() { if (inclusive) { return '[on or after ' + JSON.serialize(fromDateTime) + ']'; } else { return '[after ' + JSON.serialize(fromDateTime) + ']'; } } } /** * DatetimeBefore matcher: checks if the supplied argument is before a specified datetime */ @NamespaceAccessible public class DatetimeBefore implements fflib_IMatcher { private Datetime toDatetime; private Boolean inclusive; /** * DatetimeBefore constructor * @param toDatetime The datetime to be compared * @param inclusive Whether or not dates equal to the toDatetime should be considered a match * @return fflib_MatcherDefinitions.DatetimeBefore A new DatetimeBefore instance */ public DatetimeBefore(Datetime toDatetime, Boolean inclusive) { this.toDatetime = (Datetime)validateNotNull(toDatetime); this.inclusive = (Boolean)validateNotNull(inclusive); } public Boolean matches(Object arg) { if (arg instanceof Datetime) { Datetime datetimeToCompare = (Datetime)arg; return inclusive ? datetimeToCompare <= toDatetime : datetimeToCompare < toDatetime; } return false; } public override String toString() { if (inclusive) { return '[on or before ' + JSON.serialize(toDateTime) + ']'; } else { return '[before ' + JSON.serialize(toDateTime) + ']'; } } } /** * DatetimeBetween matcher: checks if the supplied argument is between two specified datetimes */ @NamespaceAccessible public class DatetimeBetween implements fflib_IMatcher { private Datetime fromDatetime; private Boolean inclusiveFrom; private Datetime toDatetime; private Boolean inclusiveTo; /** * DatetimeBetween constructor * @param fromDatetime The lower bound datetime to be compared * @param inclusiveFrom Whether or not dates equal to the fromDatetime should be considered a match * @param toDatetime The upper bound dateetime to be compared * @param inclusiveTo Whether or not dates equal to the toDatetime should be considered a match * @return fflib_MatcherDefinitions.DatetimeBetween A new DatetimeBetween instance */ public DatetimeBetween(Datetime fromDatetime, Boolean inclusiveFrom, Datetime toDatetime, Boolean inclusiveTo) { this.fromDatetime = (Datetime)validateNotNull(fromDatetime); this.inclusiveFrom = (Boolean)validateNotNull(inclusiveFrom); this.toDatetime = (Datetime)validateNotNull(toDatetime); this.inclusiveTo = (Boolean)validateNotNull(inclusiveTo); } public Boolean matches(Object arg) { if (arg instanceof Datetime) { Datetime datetimeToCompare = (Datetime)arg; if ((inclusiveFrom ? datetimeToCompare >= fromDatetime : datetimeToCompare > fromDatetime) && (inclusiveTo ? datetimeToCompare <= toDatetime : datetimeToCompare < toDatetime)) { return true; } } return false; } public override String toString() { return String.format('[{0} {1} and {2} {3}]', new List{ inclusiveFrom ? 'on or after' : 'after', JSON.serialize(fromDateTime), inclusiveTo ? 'on or before' : 'before', JSON.serialize(toDateTime) }); } } /* * DECIMAL (AND OTHER NUMBER) MATCHERS */ /** * DecimalBetween matcher: checks if the supplied argument is between two specified decimals */ @NamespaceAccessible public class DecimalBetween implements fflib_IMatcher { private Decimal lower; private Boolean inclusiveLower; private Decimal upper; private Boolean inclusiveUpper; /** * DecimalBetween constructor * @param lower The lower bound number to be compared * @param inclusiveLower Whether or not numbers equal to lower should be considered a match * @param upper The upper bound number to be compared * @param inclusiveUpper Whether or not numbers equal to upper should be considered a match * @return fflib_MatcherDefinitions.DecimalBetween A new DecimalBetween instance */ public DecimalBetween(Decimal lower, Boolean inclusiveLower, Decimal upper, Boolean inclusiveUpper) { this.lower = (Decimal)validateNotNull(lower); this.inclusiveLower = (Boolean)validateNotNull(inclusiveLower); this.upper = (Decimal)validateNotNull(upper); this.inclusiveUpper = (Boolean)validateNotNull(inclusiveUpper); } public Boolean matches(Object arg) { if (arg != null && arg instanceof Decimal) { Decimal longArg = (Decimal)arg; if ((inclusiveLower ? longArg >= lower : longArg > lower) && (inclusiveUpper ? longArg <= upper : longArg < upper)) { return true; } } return false; } public override String toString() { return String.format('{0} {1} and {2} {3}', new List{ inclusiveLower ? 'greater than or equal to' : 'greater than', '' + lower, inclusiveUpper ? 'less than or equal to' : 'less than', '' + upper }); } } /** * DecimalLessThan matcher: checks if the supplied argument is less than a specified decimal */ @NamespaceAccessible public class DecimalLessThan implements fflib_IMatcher { private Decimal toMatch; private Boolean inclusive; /** * DecimalLessThan constructor * @param toMatch The number to be compared against * @param inclusive Whether or not numbers equal to toMatch should be considered a match * @return fflib_MatcherDefinitions.DecimalLessThan A new DecimalLessThan instance */ public DecimalLessThan(Decimal toMatch, Boolean inclusive) { this.toMatch = (Decimal)validateNotNull(toMatch); this.inclusive = (Boolean)validateNotNull(inclusive); } public Boolean matches(Object arg) { if (arg != null && arg instanceof Decimal) { Decimal longArg = (Decimal)arg; return inclusive ? longArg <= toMatch : longArg < toMatch; } return false; } public override String toString() { if (inclusive) { return '[less than or equal to ' + toMatch + ']'; } else { return '[less than ' + toMatch + ']'; } } } /** * DecimalMoreThan matcher: checks if the supplied argument is greater than a specified decimal */ @NamespaceAccessible public class DecimalMoreThan implements fflib_IMatcher { private Decimal toMatch; private Boolean inclusive; /** * DecimalMoreThan constructor * @param toMatch The number to be compared against * @param inclusive Whether or not numbers equal to toMatch should be considered a match * @return fflib_MatcherDefinitions.DecimalMoreThan A new DecimalMoreThan instance */ public DecimalMoreThan(Decimal toMatch, Boolean inclusive) { this.toMatch = (Decimal)validateNotNull(toMatch); this.inclusive = (Boolean)validateNotNull(inclusive); } public Boolean matches(Object arg) { if (arg != null && arg instanceof Decimal) { Decimal longArg = (Decimal)arg; return inclusive ? longArg >= toMatch : longArg > toMatch; } return false; } public override String toString() { if (inclusive) { return '[greater than or equal to ' + toMatch + ']'; } else { return '[greater than ' + toMatch + ']'; } } } /** * FIELDSET MATCHERS */ /** * FieldSetEquivalentTo matcher: checks the supplied argument is a field set with the same field set members as a specified field set * This matcher is needed because equivalent FieldSets do not pass == checks, and we can't override equals/hashcode on FieldSets. */ @NamespaceAccessible public class FieldSetEquivalentTo implements fflib_IMatcher { private final Set toMatch; /* * Dirty test-only constructor, allowing us to test this class even if there are no field sets defined in the current org. */ @TestVisible public FieldSetEquivalentTo() { this.toMatch = null; } public FieldSetEquivalentTo(Schema.FieldSet toMatch) { this.toMatch = new Set(((Schema.FieldSet)validateNotNull(toMatch)).getFields()); } public Boolean matches(Object arg) { return (toMatch != null && arg != null && arg instanceof Schema.FieldSet) ? toMatch == new Set(((FieldSet)arg).getFields()) : false; } public override String toString() { return '[FieldSet with fields ' + fflib_MatcherDefinitions.stringify(toMatch) + ']'; } } /* * IS MATCHERS */ /** * IsNotNull matcher: checks the supplied argument is not null @NamespaceAccessible */ public class IsNotNull implements fflib_IMatcher { public Boolean matches(Object arg) { return arg != null; } public override String toString() { return '[is not null]'; } } /** * IsNull matcher: checks the supplied argument is null */ @NamespaceAccessible public class IsNull implements fflib_IMatcher { public Boolean matches(Object arg) { return arg == null; } public override String toString() { return '[is null]'; } } /* * LIST MATCHERS */ /** * ListContains matcher: checks if the supplied argument is equal (==) to any of the elements in a specified list */ @NamespaceAccessible public class ListContains implements fflib_IMatcher { private Object toMatch; /** * ListContains constructor * @param toMatch The list of objects to be compared * @return fflib_MatcherDefinitions.ListContains A new ListContains instance */ public ListContains(Object toMatch) { this.toMatch = toMatch; } public Boolean matches(Object arg) { if (arg != null && arg instanceof List) { for (Object o : (List)arg) { if (o == toMatch) { return true; } } } return false; } public override String toString() { return '[list containing ' + fflib_MatcherDefinitions.stringify(toMatch) + ']'; } } /** * ListIsEmpty matcher: checks if the supplied argument is an empty list @NamespaceAccessible */ public class ListIsEmpty implements fflib_IMatcher { public Boolean matches(Object arg) { return arg != null && arg instanceof List && ((List)arg).isEmpty(); } public override String toString() { return '[empty list]'; } } /* * SOBJECT MATCHERS */ /** * SObjectOfType matcher: checks if the supplied argument has the specified SObjectType @NamespaceAccessible */ public class SObjectOfType implements fflib_IMatcher { private Schema.SObjectType objectType; /** * SObjectOfType constructor * @param objectType The SObjectType to be compared * @return fflib_MatcherDefinitions.SObjectOfType A new SObjectOfType instance */ public SObjectOfType(Schema.SObjectType objectType) { this.objectType = (Schema.SObjectType)validateNotNull(objectType); } public Boolean matches(Object arg) { if (arg != null && arg instanceof SObject) { SObject soArg = (SObject)arg; return soArg.getSObjectType() == objectType; } return false; } public override String toString() { return '[SObject of type ' + objectType + ']'; } } /** * SObjectWith matcher: compares the supplied argument against a Map, representing fields and their expected values. * Note. this method silently catches exceptions getting values for the supplied fields from the arguments supplied in method calls. * * If your matcher is mysteriously failing for your SObject record, it may be getting silent 'SObject row was retrieved via SOQL without querying * the requested field' exceptions, because you haven't queried all of the fields used in this matcher. */ @NamespaceAccessible public class SObjectWith implements fflib_IMatcher { private Map toMatch; /** * SObjectWith constructor * @param toMatch A map of fields to their values to be compared. We compare each of these fields against the supplied sobject's field values. * @return fflib_MatcherDefinitions.SObjectWith A new SObjectWith instance */ public SObjectWith(Map toMatch) { this.toMatch = validate(toMatch); } public Boolean matches(Object arg) { if (arg != null && arg instanceof SObject) { SObject soArg = (SObject)arg; if (!sobjectMatches(soArg,this.toMatch)) { return false; } return true; } return false; } private Map validate(Map arg) { if (arg == null || arg.isEmpty()) { throw new fflib_ApexMocks.ApexMocksException('Arg cannot be null/empty: ' + arg); } return arg; } public override String toString() { return '[SObject with fields ' + fflib_MatcherDefinitions.stringify(toMatch) + ']'; } } /** * SObjectsWith matcher: compares the supplied list argument against a list>, representing fields and their expected values. * Each list element represents one Sobject in a list supplied to a mocked method that accepts list. * Each list element that is a map is compared against the equivalent argument list element position * * Example: * You use uow.registerNew(someListofAccounts). You mock uow in the testmethod. * toMatch is new list { * new map {Account.Name => 'foo'}, * new map {Account.Name => 'bar'} * } * By default, matchers compare against argument elements in order, viz: * The matcher will compare the first Account in the list passed to uow.registerNew to the first map of field values (i.e. Account[0].Name must be 'foo') * The matcher then compares the second Account in the list passed to uow.registerNew to the second map of field values (i.e. Account[1].Name must be 'bar') * * Optional second argument matchInOrderr if false means that each argument element is compared against all matcher elements * if everuy argument is matched exactly once and no matcher matches more than once, then the match is true * * If the arity of the list passed in the mocked method doesn't agree with the arity of the map of expected field values, false is returned * * Note. this method silently catches exceptions getting values for the supplied fields from the arguments supplied in method calls. * * If your matcher is mysteriously failing for your SObject record, it may be getting silent 'SObject row was retrieved via SOQL without querying * the requested field' exceptions, because you haven't queried all of the fields used in this matcher. */ @NamespaceAccessible public class SObjectsWith implements fflib_IMatcher { private list> toMatch; private Boolean matchInOrder { get { return matchInOrder == null ? false : matchInOrder; } set; } /** * SObjectsWith constructor * @param toMatch A list of maps of fields to their values to be compared. We compare each of these fields against the supplied list of sobject's field values. * @return fflib_MatcherDefinitions.SObjectWith A new SObjectWith instance */ public SObjectsWith(list> toMatch, Boolean matchInOrder) { this.toMatch = validate(toMatch); this.matchInOrder = matchInOrder; } public SObjectsWith(list> toMatch) { this.toMatch = validate(toMatch); this.matchInOrder = true; } public Boolean matches(Object arg) { if (arg != null && arg instanceof list) { SObject[] sobjsArg = (SObject[])arg; list> toMatches = new list>(); // Counters for matchInOrder = false; not relevant for matchInOrder = true list argMatchedCounts = new list(); // # times matched by a matcher. anything other than 1 is match error list matcherMatchedCounts = new list(); // for each map // # args that match it. Anything other than 1 is match error for (map mtchElm : toMatch) { toMatches.add(mtchElm); matcherMatchedCounts.add(0); } if (sobjsArg.size() != toMatches.size()) // arity of arguments to mocked method doesn't agree with arity of expected matches { return false; } if (matchInOrder) { for (Integer i = 0; i < sobjsArg.size(); i++) { // match in order (toMatch[i] must match arg[i]) if (!sobjectMatches(sobjsArg[i],toMatches[i])) { return false; } } return true; } else { // match in any order (but every arg must be matched only once) for (Integer i = 0; i < sobjsArg.size(); i++) { argMatchedCounts.add(0); // For each arg passed to mocked method, see if any match in the list of match field maps. // Loop within loop so not hugely efficient but there are no IDs to rely on. // Avoid unit test methods that build huge lists of expected results for (Integer m = 0; m < toMatches.size(); m++) { if (sobjectMatches(sobjsArg[i],toMatches[m])) { argMatchedCounts[i] ++; matcherMatchedCounts[m] ++; } } } // Check to see that every arg was matched only once // Check to see that every matcher matched only once // Anything else is a match fail for (Integer i=0; i < argMatchedCounts.size(); i++) { if (argMatchedCounts[i] != 1 || matcherMatchedCounts[i] != 1) { return false; } } return true; } } return false; } private list> validate(list> arg) { if (arg == null || arg.isEmpty() ) { throw new fflib_ApexMocks.ApexMocksException('Arg cannot be null/empty/other than list of map: ' + arg); } return arg; } public override String toString() { if (matchInOrder) { return '[ordered SObjects with ' + fflib_MatcherDefinitions.stringify(toMatch) + ']'; } else { return '[unordered SObjects with ' + fflib_MatcherDefinitions.stringify(toMatch) + ']'; } } } /** * helper for the sObjectWith, sObjectsWith matchers * Compares to see if the field values in toMatch exist in the sobj **/ private static Boolean sObjectMatches(Sobject sobj, map toMatch) { for (Schema.SObjectField f : toMatch.keySet()) { Object valueToMatch = toMatch.get(f); try { if (sobj.get(f) != valueToMatch) { return false; } } catch (Exception e) { //If we fail to get the value for a field it's either: // - 'SObject row was retrieved via SOQL without querying the requested field' as a mismatch // - System.SObjectException - Account.Id does not belong to SObject type Opportunity //Don't care too much, just treat this as a mismatch. return false; } } return true; // map of expected fieldvals found in sobj arg } /** * SObjectWithId matcher: checks if the supplied argument has the specified Id */ @NamespaceAccessible public class SObjectWithId implements fflib_IMatcher { private Id toMatch; /** * SObjectWithId constructor * @param toMatch The Id to be compared * @return fflib_MatcherDefinitions.SObjectWithId A new SObjectWithId instance */ public SObjectWithId(Id toMatch) { this.toMatch = (Id)validateNotNull(toMatch); } public Boolean matches(Object arg) { if (arg != null && arg instanceof SObject) { SObject soArg = (SObject)arg; return soArg.Id == toMatch; } return false; } public override String toString() { return '[SObject with Id "' + toMatch + '"]'; } } /** * SObjectWithName matcher: checks if the supplied argument has the specified Name @NamespaceAccessible */ public class SObjectWithName implements fflib_IMatcher { private String toMatch; /** * SObjectWithName constructor * @param toMatch The name to be compared * @return fflib_MatcherDefinitions.SObjectWithName A new SObjectWithName instance */ public SObjectWithName(String toMatch) { this.toMatch = (String)validateNotNull(toMatch); } public Boolean matches(Object arg) { if (arg != null && arg instanceof SObject) { SObject soArg = (SObject)arg; Schema.DescribeSObjectResult describe = soArg.getSObjectType().getDescribe(); for (Schema.SObjectField f : describe.fields.getMap().values()) { if (f.getDescribe().isNameField()) { return soArg.get(f) == toMatch; } } } return false; } public override String toString() { return '[SObject with Name "' + toMatch + '"]'; } } /* * STRING MATCHERS */ /** * StringContains matcher: checks if the supplied argument contains the specified substring */ @NamespaceAccessible public class StringContains implements fflib_IMatcher { private String toMatch; /** * StringContains constructor * @param toMatch The substring to be compared * @return fflib_MatcherDefinitions.StringContains A new StringContains instance */ public StringContains(String toMatch) { this.toMatch = (String)validateNotNull(toMatch); } public Boolean matches(Object arg) { return arg != null && arg instanceof String ? ((String)arg).contains(toMatch) : false; } public override String toString() { return '[contains "' + toMatch + '"]'; } } /** * StringEndsWith matcher: checks if the supplied argument ends with the specified substring */ @NamespaceAccessible public class StringEndsWith implements fflib_IMatcher { private String toMatch; /** * StringEndsWith constructor * @param toMatch The substring to be compared * @return fflib_MatcherDefinitions.StringEndsWith A new StringEndsWith instance */ public StringEndsWith(String toMatch) { this.toMatch = (String)validateNotNull(toMatch); } public Boolean matches(Object arg) { return arg != null && arg instanceof String ? ((String)arg).endsWith(toMatch) : false; } public override String toString() { return '[ends with "' + toMatch + '"]'; } } /** * StringIsBlank matcher: checks if the supplied argument is a blank String @NamespaceAccessible */ public class StringIsBlank implements fflib_IMatcher { public Boolean matches(Object arg) { return arg == null || (arg instanceof String ? String.isBlank((String)arg) : false); } public override String toString() { return '[blank String]'; } } /** @NamespaceAccessible * StringIsNotBlank matcher: checks if the supplied argument is a non-blank string */ public class StringIsNotBlank implements fflib_IMatcher { public Boolean matches(Object arg) { return (arg != NULL && arg instanceof String) ? String.isNotBlank((String)arg) : false; } public override String toString() { return '[non-blank String]'; } } /** * StringMatches matcher: checks if the supplied argument matches the specified regex expression */ @NamespaceAccessible public class StringMatches implements fflib_IMatcher { private Pattern pat; private final String regEx; /** * StringMatches constructor * @param toMatch The substring to be compared * @return fflib_MatcherDefinitions.StringMatches A new StringMatches instance */ public StringMatches(String regEx) { this.regEx = regEx; this.pat = Pattern.compile((String)validateNotNull(regEx)); } public Boolean matches(Object arg) { return arg != null && arg instanceof String ? pat.matcher((String)arg).matches() : false; } public override String toString() { return '[matches regex "' + regEx + '"]'; } } /** * StringStartsWith matcher: checks if the supplied argument starts with the specified substring */ @NamespaceAccessible public class StringStartsWith implements fflib_IMatcher { private String toMatch; /** * StringStartsWith constructor * @param toMatch The substring to be compared * @return fflib_MatcherDefinitions.StringStartsWith A new StringStartsWith instance */ public StringStartsWith(String toMatch) { this.toMatch = (String)validateNotNull(toMatch); } public Boolean matches(Object arg) { return arg != null && arg instanceof String ? ((String)arg).startsWith(toMatch) : false; } public override String toString() { return '[starts with "' + toMatch + '"]'; } } /* * Helpers */ private static Object validateNotNull(Object arg) { if (arg == null) { throw new fflib_ApexMocks.ApexMocksException('Arg cannot be null: ' + arg); } return arg; } public static String stringify(Object value) { try { return JSON.serialize(value, false); } catch (Exception error) { return '' + value; } } } ================================================ FILE: sfdx-source/apex-mocks/main/classes/fflib_MatcherDefinitions.cls-meta.xml ================================================ 63.0 ================================================ FILE: sfdx-source/apex-mocks/main/classes/fflib_MatchersReturnValue.cls ================================================ /** * Copyright (c) 2014-2016, FinancialForce.com, inc * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * - Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * - Neither the name of the FinancialForce.com, inc nor the names of its contributors * may be used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ @NamespaceAccessible public with sharing class fflib_MatchersReturnValue { public List matchers; public fflib_MethodReturnValue returnValue; public fflib_MatchersReturnValue(List matchers, fflib_MethodReturnValue returnValue) { this.matchers = matchers; this.returnValue = returnValue; } } ================================================ FILE: sfdx-source/apex-mocks/main/classes/fflib_MatchersReturnValue.cls-meta.xml ================================================ 63.0 ================================================ FILE: sfdx-source/apex-mocks/main/classes/fflib_MethodArgValues.cls ================================================ /** * Copyright (c) 2014-2016, FinancialForce.com, inc * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * - Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * - Neither the name of the FinancialForce.com, inc nor the names of its contributors * may be used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ @NamespaceAccessible public with sharing class fflib_MethodArgValues { public List argValues; /** * Wrapper object which encapsulates the argument values * supplied during a given method call. * @param argValues The * @return fflib_MethodArgValues The method argument wrapper object */ @NamespaceAccessible public fflib_MethodArgValues(List argValues) { this.argValues = argValues; } /** * Standard equals override. * @param other The object whose equality we are verifying * @return Boolean True if meaningfully equivalent, false otherwise. */ public Boolean equals(Object other) { if (this === other) { return true; } fflib_MethodArgValues that = other instanceof fflib_MethodArgValues ? (fflib_MethodArgValues)other : null; return that != null && this.argValues == that.argValues; } /** * Standard hashCode override. * @return Integer The generated hashCode */ public Integer hashCode() { Integer prime = 31; Integer result = 1; result = prime * result + ((argValues == null) ? 0 : argValues.hashCode()); return result; } } ================================================ FILE: sfdx-source/apex-mocks/main/classes/fflib_MethodArgValues.cls-meta.xml ================================================ 63.0 ================================================ FILE: sfdx-source/apex-mocks/main/classes/fflib_MethodCountRecorder.cls ================================================ /* Copyright (c) 2014-2017 FinancialForce.com, inc. All rights reserved. */ /** * @group Core */ @NamespaceAccessible public with sharing class fflib_MethodCountRecorder { /* * Map of method arguments by type name. * * Key: qualifiedMethod * Object: list of method arguments. * * Object: map of count by method call argument. */ private static Map> methodArgumentsByTypeName = new Map>(); private static List orderedMethodCalls = new List(); /** * Getter for the list of the methods ordered calls. * @return The list of methods called in order. */ public static List getOrderedMethodCalls() { return orderedMethodCalls; } /** * Getter for the map of the method's calls with the related arguments. * @return The map of methods called with the arguments. */ public static Map> getMethodArgumentsByTypeName() { return methodArgumentsByTypeName; } /** * Record a method was called on a mock object. * @param invocation The object holding all the data of the invocation, like the method and arguments and the mock instance. */ public void recordMethod(fflib_InvocationOnMock invocation) { List methodArgs = methodArgumentsByTypeName.get(invocation.getMethod()); if (methodArgs == null) { methodArgs = new List(); methodArgumentsByTypeName.put(invocation.getMethod(), methodArgs); } methodArgs.add(invocation.getMethodArgValues()); orderedMethodCalls.add(invocation); } } ================================================ FILE: sfdx-source/apex-mocks/main/classes/fflib_MethodCountRecorder.cls-meta.xml ================================================ 63.0 ================================================ FILE: sfdx-source/apex-mocks/main/classes/fflib_MethodReturnValue.cls ================================================ /* * Copyright (c) 2014-2017, FinancialForce.com, inc * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * - Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * - Neither the name of the FinancialForce.com, inc nor the names of its contributors * may be used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * @group Core * Class defining a method return value. */ @isTest @NamespaceAccessible public with sharing class fflib_MethodReturnValue { private StandardAnswer basicAnswer = new StandardAnswer(); /** * Instance of the implementation of the Answer interface that implements the answer, * if an answer isn't explicitly set the standard answer will be used, which just returns the stubbed return value. */ public fflib_Answer Answer { get; set; } /** * Setup a stubbed return value. * @param value The value to return from the stubbed method call. * @return The fflib_MethodReturnValue instance to allow you to chain the methods. */ @NamespaceAccessible public fflib_MethodReturnValue thenReturn(Object value) { thenAnswer(this.basicAnswer.setValue(value)); return this; } /** * Setup a stubbed exception. * @param e The exception to throw from the stubbed method call. * @return The fflib_MethodReturnValue instance to allow you to chain the methods. */ @NamespaceAccessible public fflib_MethodReturnValue thenThrow(Exception e) { thenAnswer(this.basicAnswer.setValue(e)); return this; } /** * Setup a stubbed answer. * @param answer The answer to run from the stubbed method call. */ @NamespaceAccessible public void thenAnswer(fflib_Answer answer) { this.Answer = answer; } /** * Setup a list of stubbed return values. * @param values The values to return from the stubbed method call in consecutive calls. * @return The fflib_MethodReturnValue instance to allow you to chain the methods. */ @NamespaceAccessible public fflib_MethodReturnValue thenReturnMulti(List values) { thenAnswer(this.basicAnswer.setValues(values)); return this; } /** * Setup a list stubbed exceptions. * @param es The exceptions to throw from the stubbed method call in consecutive calls. * @return The fflib_MethodReturnValue instance to allow you to chain the methods. */ @NamespaceAccessible public fflib_MethodReturnValue thenThrowMulti(List es) { thenAnswer(this.basicAnswer.setValues(es)); return this; } /** * @group Core * Inner class to handle all the stubs that do not use the thenAnswer method directly. * For internal use only. */ @NamespaceAccessible public class StandardAnswer implements fflib_Answer { private Integer whichStubReturnIndex = 0; /* * It stores the return values for the method stubbed. * The values would be stored and then returned as part of the standard answer invocation. */ private List ReturnValues = new List(); /** * Setter of a single return value. * @param value The value to be set as return value for the StandardAnswer object. * @return The StandardAnswer instance. */ public StandardAnswer setValue(Object value) { ReturnValues.add(value); return this; } /** * Setter of the list of return values. * @param value The value to be set as return value for the StandardAnswer object. * @return the StandardAnswer instance. */ public StandardAnswer setValues(List values) { if(values == null || values.size() == 0) { throw new fflib_ApexMocks.ApexMocksException( 'The stubbing is not correct, no return values have been set.'); } ReturnValues.addAll(values); return this; } /** * Standard basic implementation for the fflib_Answer answer method, to be used as default answering. * @param invocation The invocation to answer for. * @return The ReturnValue for the method stubbed. */ public Object answer(fflib_InvocationOnMock invocation) { if(ReturnValues == null || ReturnValues.size() == 0) { throw new fflib_ApexMocks.ApexMocksException( 'The stubbing is not correct, no return values have been set.'); } Integer returnValuesSize = ReturnValues.size()-1; if(whichStubReturnIndex < returnValuesSize) { return ReturnValues[whichStubReturnIndex++]; } else { return ReturnValues[returnValuesSize]; } } } } ================================================ FILE: sfdx-source/apex-mocks/main/classes/fflib_MethodReturnValue.cls-meta.xml ================================================ 63.0 ================================================ FILE: sfdx-source/apex-mocks/main/classes/fflib_MethodReturnValueRecorder.cls ================================================ /* * Copyright (c) 2014, FinancialForce.com, inc * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * - Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * - Neither the name of the FinancialForce.com, inc nor the names of its contributors * may be used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * @group Core */ @NamespaceAccessible public with sharing class fflib_MethodReturnValueRecorder { public Boolean Stubbing { get; set; } public List DoThrowWhenExceptions { get; set; } /** * Map of matchers by method. * * Key: qualifiedMethod * Object: map of method return values by method. */ private Map> matcherReturnValuesByMethod; public fflib_MethodReturnValue MethodReturnValue { get; private set; } public fflib_MethodReturnValueRecorder() { matcherReturnValuesByMethod = new Map>(); MethodReturnValue = null; } /** * Prepare a stubbed method return value. * @param invocation The object holding all the data of the invocation, like the method and arguments and the mock instance. * @return The MethodReturnValue instance. */ public fflib_MethodReturnValue prepareMethodReturnValue(fflib_InvocationOnMock invocation) { MethodReturnValue = new fflib_MethodReturnValue(); List matcherReturnValues = matcherReturnValuesByMethod.get(invocation.getMethod()); if (matcherReturnValues == null) { matcherReturnValues = new List(); matcherReturnValuesByMethod.put(invocation.getMethod(), matcherReturnValues); } List argValues = invocation.getMethodArgValues().argValues; //Register explicit arg values as 'equals' matchers, to preserve old behaviour if (!fflib_Match.Matching) { for (Object arg : argValues) { if (arg == null) fflib_Match.isNull(); else fflib_Match.eq(arg); } } List matchers = fflib_Match.getAndClearMatchers(argValues.size()); matcherReturnValues.add(new fflib_MatchersReturnValue(matchers, MethodReturnValue)); return MethodReturnValue; } /** * Get the method return value for the given method call. * @param invocation The object holding all the data of the invocation, like the method and arguments and the mock instance. * @return The MethodReturnValue instance. */ public fflib_MethodReturnValue getMethodReturnValue(fflib_InvocationOnMock invocation) { List matchersForMethods = matcherReturnValuesByMethod.get(invocation.getMethod()); if (matchersForMethods != null) { for (Integer i = matchersForMethods.size() - 1; i >= 0; i--) { fflib_MatchersReturnValue matchersReturnValue = (fflib_MatchersReturnValue)matchersForMethods.get(i); if (fflib_Match.matchesAllArgs(invocation.getMethodArgValues(), matchersReturnValue.matchers)) { return matchersReturnValue.ReturnValue; } } } return null; } /** * Prepare a stubbed exceptions for a void method. * @param exps The list of exception to throw. */ public void prepareDoThrowWhenExceptions(List exps) { DoThrowWhenExceptions = exps; } } ================================================ FILE: sfdx-source/apex-mocks/main/classes/fflib_MethodReturnValueRecorder.cls-meta.xml ================================================ 63.0 ================================================ FILE: sfdx-source/apex-mocks/main/classes/fflib_MethodVerifier.cls ================================================ /* Copyright (c) 2017 FinancialForce.com, inc. All rights reserved. */ /** * This class implements the actual verification. * @group Core */ @NamespaceAccessible public abstract class fflib_MethodVerifier { /** * Verify a method was called on a mock object. * @param mockInvocation The object holding all the data of the invocation, like the method and arguments and the mock instance. * @param verificationMode The verification mode that holds the setting about how the verification should be performed. */ public void verifyMethodCall(fflib_InvocationOnMock mockInvocation, fflib_VerificationMode verificationMode) { validateMode(verificationMode); verify(mockinvocation.getMethod(), mockinvocation.getMethodArgValues(), verificationMode); } /* * Method that actually performs the verify * @param qm The method to be verified. * @param methodArg The arguments of the method that needs to be verified. * @param verificationMode The verification mode that holds the setting about how the verification should be performed. */ protected abstract void verify( fflib_QualifiedMethod qm, fflib_MethodArgValues methodArg, fflib_VerificationMode verificationMode); /* * Method that validates the verification mode used in the verify. * Not all the methods from the fflib_VerificationMode are implemented for the different classes that extends the fflib_MethodVerifier. * The error is thrown at run time, so this method is called in the method that actually performs the verify. * @param verificationMode The verification mode that has to have been verified. * @throws Exception with message for the fflib_VerificationMode not implemented. */ protected abstract void validateMode(fflib_VerificationMode verificationMode); /* * Method that performs the argument capturing. * Captures argument values during verification. * @param matchers The list of matcher with which a method is verified. */ protected void capture(List matchers) { for(fflib_IMatcher matcher : matchers) { if( matcher instanceof fflib_ArgumentCaptor.AnyObject ) { ((fflib_ArgumentCaptor.AnyObject)matcher).storeArgument(); } } } protected void throwException( fflib_QualifiedMethod qm, String inOrder, Integer expectedCount, String qualifier, Integer methodCount, String customAssertMessage, fflib_MethodArgValues expectedArguments, List expectedMatchers, List actualArguments) { String template = 'EXPECTED COUNT: {0}{1}{2}' // qualified expected count (e.g. "3 or fewer times in order") + '\nACTUAL COUNT: {3}' // actual count + '\nMETHOD: {4}' // method signature + '{5}'; // custom assert message String expectedDescription = ''; String actualDescription = ''; if (qm.hasArguments()) { template += '\n---' // separator + '\nACTUAL ARGS: {6}' // actual args + '\n---' // separator + '\nEXPECTED ARGS: {7}'; // matcher descriptions if (expectedMatchers == null) { expectedDescription = describe(expectedArguments); } else { expectedDescription = describe(expectedMatchers); } actualDescription = describe(actualArguments); } String message = String.format(template, new List{ '' + expectedCount, String.isBlank(qualifier) ? '' : ('' + qualifier), inOrder, '' + methodCount, '' + qm, String.isBlank(customAssertMessage) ? '' : ('\n' + customAssertMessage), actualDescription, expectedDescription }); throw new fflib_ApexMocks.ApexMocksException(message); } private static String describe(List matchers) { List descriptions = new List(); for (fflib_IMatcher matcher : matchers) { descriptions.add('' + matcher); } return String.join(descriptions, ', '); } private static String describe(List valuesFromAllInvocations) { List descriptions = new List(); if (valuesFromAllInvocations != null) { for (fflib_MethodArgValues valuesFromOneInvocation : valuesFromAllInvocations) { descriptions.add(describe(valuesFromOneInvocation)); } } return '(' + String.join(descriptions, '), (') + ')'; } private static String describe(fflib_MethodArgValues values) { List descriptions = new List(); for (Object value : values.argValues) { try { // Attempt to JSON serialize - that way it doesn't truncate SObject fields etc. // Bear in mind that something are not JSON serializable, e.g. things with circular references. descriptions.add(JSON.serialize(value)); } catch (Exception error) { descriptions.add('' + value); } } return String.join(descriptions, ', '); } } ================================================ FILE: sfdx-source/apex-mocks/main/classes/fflib_MethodVerifier.cls-meta.xml ================================================ 63.0 Active ================================================ FILE: sfdx-source/apex-mocks/main/classes/fflib_QualifiedMethod.cls ================================================ /* * Copyright (c) 2016-2017 FinancialForce.com, inc. All rights reserved. */ @NamespaceAccessible public with sharing class fflib_QualifiedMethod { public final Object mockInstance; public final String typeName; public final String methodName; public final List methodArgTypes; @NamespaceAccessible public fflib_QualifiedMethod(String typeName, String methodName, List methodArgTypes) { this(typeName, methodName, methodArgTypes, null); } @NamespaceAccessible public fflib_QualifiedMethod(String typeName, String methodName, List methodArgTypes, Object mockInstance) { this.mockInstance = mockInstance; this.typeName = typeName; this.methodName = methodName; this.methodArgTypes = methodArgTypes; } /** * Standard equals override. * @param other The object whose equality we are verifying * @return Boolean True if meaningfully equivalent, false otherwise. */ public Boolean equals(Object other) { if (this === other) { return true; } fflib_QualifiedMethod that = other instanceof fflib_QualifiedMethod ? (fflib_QualifiedMethod)other : null; return that != null && (this.mockInstance === that.mockInstance || !fflib_ApexMocksConfig.HasIndependentMocks) && this.typeName == that.typeName && this.methodName == that.methodName && this.methodArgTypes == that.methodArgTypes; } /** * Standard hashCode override. * @return Integer The generated hashCode */ public Integer hashCode() { Integer prime = 31; Integer result = 1; if (fflib_ApexMocksConfig.HasIndependentMocks) { result = prime * result + ((mockInstance == null) ? 0 : mockInstance.hashCode()); } result = prime * result + ((methodArgTypes == null) ? 0 : methodArgTypes.hashCode()); result = prime * result + ((methodName == null) ? 0 : methodName.hashCode()); result = prime * result + ((typeName == null) ? 0 : typeName.hashCode()); return result; } /** * Standard toString override. * @return String The human friendly description of the method. */ public override String toString() { return typeName + '.' + methodName + methodArgTypes; } /** * Predicate describing whether the qualified method accepts arguments or not. * @return True if the method accepts arguments. */ public Boolean hasArguments() { return this.methodArgTypes != null && !this.methodArgTypes.isEmpty(); } } ================================================ FILE: sfdx-source/apex-mocks/main/classes/fflib_QualifiedMethod.cls-meta.xml ================================================ 63.0 ================================================ FILE: sfdx-source/apex-mocks/main/classes/fflib_QualifiedMethodAndArgValues.cls ================================================ /* Copyright (c) 2016-2017 FinancialForce.com, inc. All rights reserved. */ /** * @group Core */ @NamespaceAccessible public with sharing class fflib_QualifiedMethodAndArgValues { private final fflib_QualifiedMethod qm; private final fflib_MethodArgValues args; private final Object mockInstance; @NamespaceAccessible public fflib_QualifiedMethodAndArgValues(fflib_QualifiedMethod qm, fflib_MethodArgValues args, Object mockInstance) { this.qm = qm; this.args = args; this.mockInstance = mockInstance; } @NamespaceAccessible public fflib_QualifiedMethod getQualifiedMethod() { return qm; } @NamespaceAccessible public fflib_MethodArgValues getMethodArgValues() { return args; } @NamespaceAccessible public Object getMockInstance() { return mockInstance; } public override String toString() { return qm + ' with args: [' + String.join(args.argValues, '],[') + ']'; } } ================================================ FILE: sfdx-source/apex-mocks/main/classes/fflib_QualifiedMethodAndArgValues.cls-meta.xml ================================================ 63.0 Active ================================================ FILE: sfdx-source/apex-mocks/main/classes/fflib_System.cls ================================================ /* * Copyright (c) 2017 FinancialForce.com, inc. All rights reserved. */ /** * @group Core * Contains counterparts for helper methods in the native System class. */ @NamespaceAccessible public class fflib_System { /** * Verifies that the supplied argument is meaningfully equivalent to the expected argument, as defined by its matcher. * See fflib_SystemTest for examples of usage. * @param ignoredRetval Dummy value, returned on registering an fflib_IMatcher. * @param value The object instance upon which we are checking equality. */ @NamespaceAccessible public static void assertEquals(Object ignoredRetval, Object value) { assertEquals(ignoredRetval, value, null); } /** * Verifies that the supplied argument is meaningfully equivalent to the expected argument, as defined by its matcher. * See fflib_SystemTest for examples of usage. * @param ignoredRetval Dummy value, returned on registering an fflib_IMatcher. * @param value The object instance upon which we are checking equality. * @param customAssertMessage Provides context or additional information for the assertion. */ @NamespaceAccessible public static void assertEquals(Object ignoredRetval, Object value, String customAssertMessage) { fflib_IMatcher matcher = null; try { List matchers = fflib_Match.getAndClearMatchers(1); matcher = matchers[0]; } catch (fflib_ApexMocks.ApexMocksException e) { throw new fflib_ApexMocks.ApexMocksException('fflib_System.assertEquals expects you to register exactly 1 fflib_IMatcher (typically through the helpers in fflib_Match).'); } if (!matcher.matches(value)) { throw new fflib_ApexMocks.ApexMocksException(String.format('Expected : {0}, Actual: {1}{2}', new String[]{ String.valueOf(matcher), String.valueOf(value), String.isBlank(customAssertMessage) ? '' : (' -- ' + customAssertMessage) })); } } } ================================================ FILE: sfdx-source/apex-mocks/main/classes/fflib_System.cls-meta.xml ================================================ 63.0 Active ================================================ FILE: sfdx-source/apex-mocks/main/classes/fflib_VerificationMode.cls ================================================ /* Copyright (c) 2017 FinancialForce.com, inc. All rights reserved. */ /** * This class implements the verification modes with Mockito syntax style. * It can be used in the classic verify and in the ordered verify. * @group Core */ @NamespaceAccessible public with sharing class fflib_VerificationMode { public Integer VerifyMin {get; set;} public Integer VerifyMax {get; set;} public String CustomAssertMessage { get; set; } public enum ModeName {times, atLeast, atMost, between, atLeastOnce, calls} public ModeName Method; @NamespaceAccessible public fflib_VerificationMode() { VerifyMin = 1; VerifyMax = null; CustomAssertMessage = null; Method = null; } /** * Sets how many times the method is expected to be called. * For InOrder verification we copy Mockito behavior which is as follows; *
    *
  • Consume the specified number of matching invocations, ignoring non-matching invocations in between
  • *
  • Fail an assert if the very next invocation matches, but additional matches can still exist so long as at least one non-matching invocation exists before them
  • *
* For example if you had a(); a(); b(); a(); * then inOrder.verify(myMock, 2)).a(); or inOrder.verify(myMock, 3)).a(); would pass but not inOrder.verify(myMock, 1)).a(); * @param times The number of times you expect the method to have been called. * @return The fflib_VerificationMode object instance with the proper settings. */ @NamespaceAccessible public fflib_VerificationMode times(Integer times) { this.Method = ModeName.times; this.VerifyMin = this.VerifyMax = times; return this; } /** * Sets a custom assert message for the verify. * @param customAssertMessage The custom message for the assert in case the assert is false. The custom message is queued to the default message. * @return The fflib_VerificationMode object instance with the proper settings. */ @NamespaceAccessible public fflib_VerificationMode description(String customAssertMessage) { this.CustomAssertMessage = customAssertMessage; return this; } /** * Sets the minimum number of times the method is expected to be called. * With the InOrder verification it performs a greedy verification, which means it would consume all the instances of the method verified. * @param atLeastTimes The minimum number of times you expect the method to have been called. * @return The fflib_VerificationMode object instance with the proper settings. */ @NamespaceAccessible public fflib_VerificationMode atLeast(Integer atLeastTimes) { this.Method = ModeName.atLeast; this.VerifyMin = atLeastTimes; return this; } /** * Sets the maximum number of times the method is expected to be called. Not available in the InOrder verification. * @param atMostTimes The maximum number of times the method is expected to be called. * @return The fflib_VerificationMode object instance with the proper settings. */ @NamespaceAccessible public fflib_VerificationMode atMost(Integer atMostTimes) { this.Method = ModeName.atMost; this.VerifyMax = atMostTimes; return this; } /** * Sets that the method is called at least once. * With the InOrder verification it performs a greedy verification, which means it would consume all the instances of the method verified. * @return The fflib_VerificationMode object instance with the proper settings. */ @NamespaceAccessible public fflib_VerificationMode atLeastOnce() { this.Method = ModeName.atLeastOnce; this.VerifyMin = 1; return this; } /** * Sets the range of how many times the method is expected to be called. Not available in the InOrder verification. * @param atLeastTimes The minimum number of times you expect the method to have been called. * @param atMostTimes The maximum number of times the method is expected to be called. * @return The fflib_VerificationMode object instance with the proper settings. */ @NamespaceAccessible public fflib_VerificationMode between(Integer atLeastTimes, Integer atMostTimes) { this.Method = ModeName.between; this.VerifyMin = atLeastTimes; this.VerifyMax = atMostTimes; return this; } /** * Sets that the method is not expected to be called. * @return The fflib_VerificationMode object instance with the proper settings. */ @NamespaceAccessible public fflib_VerificationMode never() { this.VerifyMin = fflib_ApexMocks.NEVER; this.VerifyMax = fflib_ApexMocks.NEVER; return this; } /** * Sets how many times the method is expected to be called for an InOrder verifier. Available Only with the InOrder verification. * A verification mode using calls will not fail if the method is called more times than expected. * @param callingTimes The number of times you expect the method to have been called in the InOrder verifying (no greedy verify). * @return The fflib_VerificationMode object instance with the proper settings. */ @NamespaceAccessible public fflib_VerificationMode calls(Integer callingTimes) { this.Method = ModeName.calls; this.VerifyMin = callingTimes; this.VerifyMax = null; return this; } } ================================================ FILE: sfdx-source/apex-mocks/main/classes/fflib_VerificationMode.cls-meta.xml ================================================ 63.0 Active ================================================ FILE: sfdx-source/apex-mocks/test/classes/fflib_AnswerTest.cls ================================================ /* Copyright (c) 2017 FinancialForce.com, inc. All rights reserved. */ /** * @nodoc */ @isTest private class fflib_AnswerTest { private static fflib_InvocationOnMock actualInvocation = null; @isTest static void thatAnswersWithException() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); mocks.startStubbing(); mocks.when(mockList.get2(0, 'Hi hi Hello Hi hi')).thenAnswer(new fflib_AnswerTest.ExceptionForAnswer()); mocks.stopStubbing(); // When try { mockList.get2(0, 'Hi hi Hello Hi hi'); System.Assert.fail('an exception is expected to be thrown on the answer execution'); } catch(fflib_ApexMocks.ApexMocksException ansExpt) { String expectedMessage = 'an error occurs on the execution of the answer'; // Then System.Assert.areEqual(expectedMessage, ansExpt.getMessage(), 'the message from the answer is not as expected'); } } @isTest static void thatStoresMethodIntoInvocationOnMock() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); mocks.startStubbing(); mocks.when(mockList.get2(0, 'Hi hi Hello Hi hi')).thenAnswer(new fflib_AnswerTest.BasicAnswer()); mocks.stopStubbing(); // When mockList.get2(0, 'Hi hi Hello Hi hi'); // Then Object methodCalled = actualInvocation.getMethod(); System.Assert.isInstanceOfType(methodCalled, fflib_QualifiedMethod.class, 'the object returned is not a method as expected'); String expectedMethodSignature = fflib_MyList.getStubClassName() + '.get2(Integer, String)'; System.Assert.areEqual(expectedMethodSignature, ((fflib_QualifiedMethod)methodCalled).toString(), ' the method is no the one expected'); } @isTest static void thatAnswerOnlyForTheMethodStubbedWithAnswer() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); mocks.startStubbing(); mocks.when(mockList.get(3)).thenReturn('ted'); mocks.when(mockList.get2(0, 'Hi hi Hello Hi hi')).thenAnswer(new fflib_AnswerTest.BasicAnswer()); mocks.stopStubbing(); // When mockList.add('one'); String noAnswered = mockList.get(3); mockList.get2(0, 'Hi hi Hello Hi hi'); // Then Object methodCalled = actualInvocation.getMethod(); System.Assert.isInstanceOfType(methodCalled, fflib_QualifiedMethod.class, 'the object returned is not a method as expected'); String expectedMethodSignature = fflib_MyList.getStubClassName() + '.get2(Integer, String)'; System.Assert.areEqual(expectedMethodSignature, ((fflib_QualifiedMethod)methodCalled).toString(), ' the method is no the one expected'); System.Assert.areEqual('ted', noAnswered, 'the get method should have returned the stubbed string'); } @isTest static void thatMultipleAnswersAreHandled() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); mocks.startStubbing(); mocks.when(mockList.get(3)).thenAnswer(new fflib_AnswerTest.FirstAnswer()); mocks.when(mockList.get2(0, 'Hi hi Hello Hi hi')).thenAnswer(new fflib_AnswerTest.SecondAnswer()); mocks.stopStubbing(); // When mockList.add('one'); String answer1 = mockList.get(3); String answer2 = mockList.get2(0, 'Hi hi Hello Hi hi'); System.Assert.areEqual('this is the first answer', answer1, 'the answer wasnt the one expected'); System.Assert.areEqual('and this is the second one', answer2, 'the answer wasnt the one expected'); } @isTest static void thatStoresMockInstanceIntoInvocationOnMock() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); mocks.startStubbing(); mocks.when(mockList.get2(0, 'Hi hi Hello Hi hi')).thenAnswer(new fflib_AnswerTest.BasicAnswer()); mocks.stopStubbing(); // When String mockCalled = mockList.get2(0, 'Hi hi Hello Hi hi'); // Then System.Assert.isInstanceOfType(actualInvocation.getMock(), fflib_MyList.IList.class, 'the object returned is not a mock instance as expected'); System.Assert.areEqual(mockList, actualInvocation.getMock(), 'the mock returned should be the mockList used in the stubbing'); } @isTest static void thatMethodsParametersAreAccessible() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); mocks.startStubbing(); mocks.when(mockList.get2(0, 'Hi hi Hello Hi hi')).thenAnswer(new fflib_AnswerTest.ProcessArgumentAnswer()); mocks.stopStubbing(); // When String actualValue = mockList.get2(0, 'Hi hi Hello Hi hi'); // Then System.Assert.areEqual('Bye hi Hello Bye hi', actualValue, 'the answer is not correct'); } @isTest static void thatAnswerOnlyForTheStubbedParameter() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); mocks.startStubbing(); mocks.when(mockList.get2(0, 'Hi hi Hello Hi hi')).thenAnswer(new fflib_AnswerTest.ProcessArgumentAnswer()); mocks.stopStubbing(); // When String actualValue1 = mockList.get2(0, 'some string for my method'); String actualValue2 = mockList.get2(0, 'Hi hi Hello Hi hi'); String actualValue3 = mockList.get2(0, 'another string for the same method'); // Then System.Assert.areEqual('Bye hi Hello Bye hi', actualValue2, 'the answer is not correct'); System.Assert.areEqual(null, actualValue1, 'the answer is not correct'); System.Assert.areEqual(null, actualValue3, 'the answer is not correct'); } @isTest static void thatMethodsParametersAreAccessibleWhenCalledWithMatchers() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); mocks.startStubbing(); mocks.when(mockList.get2(fflib_Match.anyInteger(), fflib_Match.anyString())).thenAnswer(new fflib_AnswerTest.ProcessArgumentAnswer()); mocks.stopStubbing(); // When String actualValue = mockList.get2(0, 'Hi hi Hello Hi hi'); // Then System.Assert.areEqual('Bye hi Hello Bye hi', actualValue, 'the answer is not correct'); } @isTest static void thatExceptionIsThrownWhenAccessOutOfIndexArgument() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); mocks.startStubbing(); mocks.when(mockList.get2(0, 'Hi hi Hello Hi hi')).thenAnswer(new fflib_AnswerTest.ExceptionForArgumentsOutOfBound()); mocks.stopStubbing(); // When String actualValue = mockList.get2(0, 'Hi hi Hello Hi hi'); } @isTest static void thatExceptionIsThrownWhenAccessNegativeIndexArgument() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); mocks.startStubbing(); mocks.when(mockList.get2(0, 'Hi hi Hello Hi hi')).thenAnswer(new fflib_AnswerTest.ExceptionForNegativeArgumentIndex()); mocks.stopStubbing(); // When String actualValue = mockList.get2(0, 'Hi hi Hello Hi hi'); } @isTest static void thatArgumentListEmptyForMethodWithNoArgument() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); mocks.startStubbing(); mocks.when(mockList.isEmpty()).thenAnswer(new fflib_AnswerTest.ArgumentListEmptyForMethodWithNoArgument()); mocks.stopStubbing(); // When Boolean actualValue = mockList.isEmpty(); } @isTest static void thatAnswerToVoidMethod() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); mocks.startStubbing(); ((fflib_MyList) mocks.doAnswer(new fflib_AnswerTest.BasicAnswer(), mockList)).addMore('Hi hi Hello Hi hi'); mocks.stopStubbing(); // When mockList.addMore('Hi hi Hello Hi hi'); // Then Object methodCalled = actualInvocation.getMethod(); System.Assert.isInstanceOfType(methodCalled, fflib_QualifiedMethod.class, 'the object returned is not a method as expected'); String expectedMethodSignature = fflib_MyList.getStubClassName() + '.addMore(String)'; System.Assert.areEqual(expectedMethodSignature, ((fflib_QualifiedMethod)methodCalled).toString(), 'Unexpected method name: ' + methodCalled); } @isTest static void thatAnswerToVoidAndNotVoidMethods() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); mocks.startStubbing(); ((fflib_MyList) mocks.doAnswer(new fflib_AnswerTest.FirstAnswer(), mockList)).get(3); ((fflib_MyList) mocks.doAnswer(new fflib_AnswerTest.BasicAnswer(), mockList)).addMore('Hi hi Hello Hi hi'); ((fflib_MyList) mocks.doAnswer(new fflib_AnswerTest.SecondAnswer(), mockList)).get2(4, 'Hi hi Hello Hi hi'); mocks.stopStubbing(); // When String answer1 = mockList.get(3); String answer2 = mockList.get2(4, 'Hi hi Hello Hi hi'); mockList.addMore('Hi hi Hello Hi hi'); // Then Object methodCalled = actualInvocation.getMethod(); System.Assert.isInstanceOfType(methodCalled, fflib_QualifiedMethod.class, 'the object returned is not a method as expected'); String expectedMethodSignature = fflib_MyList.getStubClassName() + '.addMore(String)'; System.Assert.areEqual(expectedMethodSignature, ((fflib_QualifiedMethod)methodCalled).toString(), 'the last method called should be the addMore, so should be the last to set the actualInvocation variable.'); System.Assert.areEqual('this is the first answer', answer1, 'the answer was not the one expected'); System.Assert.areEqual('and this is the second one', answer2, 'the answer was not the one expected'); } @isTest static void thatAnswerToDifferentVoidMethods() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); fflib_AnswerTest.FirstAnswer answer1 = new fflib_AnswerTest.FirstAnswer(); fflib_AnswerTest.SecondAnswer answer2 = new fflib_AnswerTest.SecondAnswer(); System.Assert.areEqual(null, answer1.getMessage(), 'the answer message should be null at this stage'); System.Assert.areEqual(null, answer2.getMessage(), 'the answer message should be null at this stage'); mocks.startStubbing(); ((fflib_MyList) mocks.doAnswer(answer1, mockList)).addMore('Hi hi Hello Hi hi'); ((fflib_MyList) mocks.doAnswer(answer2, mockList)).add('Hello'); mocks.stopStubbing(); // When mockList.addMore('Hi hi Hello Hi hi'); mockList.add('Hello'); // Then System.Assert.areEqual('this is the first answer', answer1.getMessage(), 'the answer was not the one expected'); System.Assert.areEqual('and this is the second one', answer2.getMessage(), 'the answer was not the one expected'); } //Answers public class BasicAnswer implements fflib_Answer { public Object answer(fflib_InvocationOnMock invocation) { actualInvocation = invocation; return null; } } public class ExceptionForAnswer implements fflib_Answer { public Object answer(fflib_InvocationOnMock invocation) { actualInvocation = invocation; throw new fflib_ApexMocks.ApexMocksException('an error occurs on the execution of the answer'); } } public class ExceptionForArgumentsOutOfBound implements fflib_Answer { public Object answer(fflib_InvocationOnMock invocation) { actualInvocation = invocation; try { Object noExistingObj = invocation.getArgument(2); System.Assert.fail('an exception was expected because the argument in the method are only 2'); } catch(fflib_ApexMocks.ApexMocksException exp) { String expectedMessage = 'Invalid index, must be greater or equal to zero and less of 2.'; String actualMessage = exp.getMessage(); System.Assert.areEqual(expectedMessage, actualMessage, 'the message return by the exception is not as expected'); } return null; } } public class ExceptionForNegativeArgumentIndex implements fflib_Answer { public Object answer(fflib_InvocationOnMock invocation) { actualInvocation = invocation; try { Object noExistingObj = invocation.getArgument(-1); System.Assert.fail('an exception was expected because the argument index cannot be negative'); } catch(fflib_ApexMocks.ApexMocksException exp) { String expectedMessage = 'Invalid index, must be greater or equal to zero and less of 2.'; String actualMessage = exp.getMessage(); System.Assert.areEqual(expectedMessage, actualMessage, 'the message return by the exception is not as expected'); } return null; } } public class ArgumentListEmptyForMethodWithNoArgument implements fflib_Answer { public Object answer(fflib_InvocationOnMock invocation) { actualInvocation = invocation; List emptyList = invocation.getArguments(); System.Assert.areEqual(0, emptyList.size(), 'the argument list from a method without arguments should be empty'); return null; } } public class FirstAnswer implements fflib_Answer { private String answerMessage; public String getMessage() { return this.answerMessage; } public Object answer(fflib_InvocationOnMock invocation) { actualInvocation = invocation; this.answerMessage = 'this is the first answer'; return answerMessage; } } public class SecondAnswer implements fflib_Answer { private String answerMessage; public String getMessage() { return this.answerMessage; } public Object answer(fflib_InvocationOnMock invocation) { actualInvocation = invocation; this.answerMessage = 'and this is the second one'; return answerMessage; } } public class ProcessArgumentAnswer implements fflib_Answer { public Object answer(fflib_InvocationOnMock invocation) { actualInvocation = invocation; String argument = (String) invocation.getArgument(1); System.Assert.areNotEqual(null, argument, ' the argument should have some value'); argument = argument.replace('Hi', 'Bye'); return argument; } } } ================================================ FILE: sfdx-source/apex-mocks/test/classes/fflib_AnswerTest.cls-meta.xml ================================================ 63.0 Active ================================================ FILE: sfdx-source/apex-mocks/test/classes/fflib_AnyOrderTest.cls ================================================ /* Copyright (c) 2017 FinancialForce.com, inc. All rights reserved. */ /** * @nodoc */ @isTest private class fflib_AnyOrderTest { /* * replicating the apex mocks tests with the new syntax */ @isTest private static void whenVerifyMultipleCallsWithMatchersShouldReturnCorrectMethodCallCounts() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); // 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')); } @isTest private static void whenVerifyWithCombinedMatchersShouldReturnCorrectMethodCallCounts() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); // 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')) ); } @isTest private static void whenVerifyCustomMatchersCanBeUsed() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); // 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((Integer)fflib_Match.matches(new isOdd())); ((fflib_MyList.IList) mocks.verify(mockList, mocks.times(2))).get((Integer)fflib_Match.matches(new isEven())); } @isTest private static void verifyMultipleMethodCallsWithSameSingleArgument() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); // When mockList.add('bob'); mockList.add('bob'); // Then ((fflib_MyList.IList) mocks.verify(mockList, mocks.times(2))).add('bob'); } @isTest private static void verifyMethodNotCalled() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); // When mockList.get(0); // Then ((fflib_MyList.IList) mocks.verify(mockList, mocks.never())).add('bob'); ((fflib_MyList.IList) mocks.verify(mockList)).get(0); } @isTest private static void verifySingleMethodCallWithMultipleArguments() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); // When mockList.set(0, 'bob'); // Then ((fflib_MyList.IList) mocks.verify(mockList)).set(0, 'bob'); ((fflib_MyList.IList) mocks.verify(mockList, mocks.never())).set(0, 'fred'); } @isTest private static void verifyMethodCallWhenNoCallsBeenMadeForType() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); // Then ((fflib_MyList.IList) mocks.verify(mockList, mocks.never())).add('bob'); } @isTest private static void whenVerifyMethodNeverCalledMatchersAreReset() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); // When mockList.add('bob'); // Then ((fflib_MyList.IList) mocks.verify(mockList, mocks.never())).get(fflib_Match.anyInteger()); ((fflib_MyList.IList) mocks.verify(mockList)).add(fflib_Match.anyString()); } /* * times */ @isTest private static void verifyTimesMethodHasBeenCalled() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); // When mockList.add('bob'); mockList.add('bob'); mockList.add('bob'); // Then ((fflib_MyList.IList) mocks.verify(mockList, mocks.times(3))).add('bob'); } @isTest private static void verifyTimesMethodHasBeenCalledWithMatchers() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); // When mockList.add('bob1'); mockList.add('bob2'); mockList.add('bob3'); // Then ((fflib_MyList.IList) mocks.verify(mockList, mocks.times(3))).add(fflib_Match.anyString()); } @isTest private static void thatVerifyTimesMethodFailsWhenCalledLessTimes() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); // When mockList.add('bob'); mockList.add('bob'); mockList.add('bob'); // Then try { ((fflib_MyList.IList) mocks.verify(mockList, mocks.times(4))).add('bob'); System.Assert.fail('an exception was expected'); } catch(Exception exc) { assertFailMessage(exc.getMessage(), 4, 3); } } @isTest private static void thatVerifyTimesMethodFailsWhenCalledMoreTimes() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); // When mockList.add('bob'); mockList.add('bob'); mockList.add('bob'); // Then try { ((fflib_MyList.IList) mocks.verify(mockList, mocks.times(2))).add('bob'); System.Assert.fail('an exception was expected'); } catch(Exception exc) { assertFailMessage(exc.getMessage(), 2, 3); } } @isTest private static void thatVerifyTimesMethodFailsWhenCalledLessTimesWithMatchers() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); // When mockList.add('bob'); mockList.add('bob'); mockList.add('bob'); // Then try { ((fflib_MyList.IList) mocks.verify(mockList, mocks.times(4))).add(fflib_Match.anyString()); System.Assert.fail('an exception was expected'); } catch(Exception exc) { assertFailMessage(exc.getMessage(), 4, 3); } } @isTest private static void thatVerifyTimesMethodFailsWhenCalledMoreTimesWithMatchers() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); // 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.fail('an exception was expected'); } catch(Exception exc) { assertFailMessage(exc.getMessage(), 2, 3); } } /* * description */ @isTest private static void thatCustomMessageIsAdded() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); // 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.fail('an exception was expected'); } catch(Exception exc) { System.Assert.areEqual('EXPECTED COUNT: 2' + '\nACTUAL COUNT: 3' + '\nMETHOD: fflib_MyList__sfdc_ApexStub.add(String)' + '\nCustom message to explain the reason of the verification' + '\n---' + '\nACTUAL ARGS: ("bob"), ("bob"), ("bob")' + '\n---' + '\nEXPECTED ARGS: [any String]', exc.getMessage(), 'Unexpected verify fail message'); } } /* * atLeast */ @isTest private static void thatVerifiesAtLeastNumberOfTimes() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); // When mockList.add('bob'); mockList.add('fred'); mockList.add('bob'); mockList.add('bob'); // Then ((fflib_MyList.IList) mocks.verify(mockList, mocks.atLeast(2))).add('bob'); } @isTest private static void thatVerifiesAtLeastNumberOfTimesWhenIsCalledMoreTimes() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); // When mockList.add('bob'); mockList.add('fred'); mockList.add('bob'); mockList.add('fred'); mockList.add('bob'); mockList.add('fred'); // Then ((fflib_MyList.IList) mocks.verify(mockList, mocks.atLeast(2))).add('bob'); } @isTest private static void thatThrownExceptionIfCalledLessThanAtLeastNumberOfTimes() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); // When mockList.add('bob'); mockList.add('fred'); mockList.add('bob'); // Then try { ((fflib_MyList.IList) mocks.verify(mockList, mocks.atLeast(3))).add('bob'); System.Assert.fail('an exception was expected because we are asserting that the method is called 3 times when instead is called only twice'); } catch(fflib_ApexMocks.ApexMocksException ex) { System.Assert.areEqual('EXPECTED COUNT: 3 or more times' + '\nACTUAL COUNT: 2' + '\nMETHOD: fflib_MyList__sfdc_ApexStub.add(String)' + '\n---' + '\nACTUAL ARGS: ("bob"), ("fred"), ("bob")' + '\n---' + '\nEXPECTED ARGS: "bob"', ex.getMessage(), 'Unexpected verify fail message'); } } @isTest private static void thatVerifiesAtLeastNumberOfTimesWithMatchers() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); // When mockList.add('bob'); mockList.add('fred'); // Then ((fflib_MyList.IList) mocks.verify(mockList, mocks.atLeast(2))).add(fflib_Match.anyString()); } @isTest private static void thatVerifiesAtLeastNumberOfTimesWhenIsCalledMoreTimesWithMatchers() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); // When mockList.add('bob'); mockList.add('fred'); mockList.add('fred'); mockList.add('fred'); // Then ((fflib_MyList.IList) mocks.verify(mockList, mocks.atLeast(2))).add(fflib_Match.anyString()); } @isTest private static void thatThrownExceptionIfCalledLessThanAtLeastNumberOfTimesWithMatchers() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); // When mockList.add('bob'); mockList.add('fred'); // Then try { ((fflib_MyList.IList) mocks.verify(mockList, mocks.atLeast(3))).add(fflib_Match.anyString()); System.Assert.fail('an exception was expected because we are asserting that the method is called 3 times when instead is called only twice'); } catch(fflib_ApexMocks.ApexMocksException ex) { System.Assert.areEqual('EXPECTED COUNT: 3 or more times' + '\nACTUAL COUNT: 2' + '\nMETHOD: fflib_MyList__sfdc_ApexStub.add(String)' + '\n---' + '\nACTUAL ARGS: ("bob"), ("fred")' + '\n---' + '\nEXPECTED ARGS: [any String]', ex.getMessage(), 'Unexpected verify fail message'); } } /* * atMost */ @isTest private static void thatVerifiesAtMostNumberOfTimes() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); // When mockList.add('bob'); mockList.add('fred'); mockList.add('bob'); mockList.add('bob'); mockList.add('fred'); // Then ((fflib_MyList.IList) mocks.verify(mockList, mocks.atMost(5))).add('bob'); } @isTest private static void thatVerifiesAtMostSameNumberOfTimes() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); // When mockList.add('bob'); mockList.add('fred'); mockList.add('bob'); mockList.add('bob'); mockList.add('fred'); // Then ((fflib_MyList.IList) mocks.verify(mockList, mocks.atMost(3))).add('bob'); } @isTest private static void thatThrownExceptionIfCalledMoreThanAtMostNumberOfTimes() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); // When mockList.add('bob'); mockList.add('fred'); mockList.add('fred'); mockList.add('bob'); mockList.add('bob'); mockList.add('bob'); mockList.add('fred'); // Then try { ((fflib_MyList.IList) mocks.verify(mockList, mocks.atMost(3))).add('bob'); System.Assert.fail('an exception was expected because we are asserting that the method is called 3 times when instead is called four times'); } catch(fflib_ApexMocks.ApexMocksException ex) { System.Assert.areEqual('EXPECTED COUNT: 3 or fewer times' + '\nACTUAL COUNT: 4' + '\nMETHOD: fflib_MyList__sfdc_ApexStub.add(String)' + '\n---' + '\nACTUAL ARGS: ("bob"), ("fred"), ("fred"), ("bob"), ("bob"), ("bob"), ("fred")' + '\n---' + '\nEXPECTED ARGS: "bob"', ex.getMessage(), 'Unexpected verify fail message'); } } @isTest private static void thatVerifiesAtMostNumberOfTimesWithMatchers() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); // When mockList.add('bob'); mockList.add('fred'); mockList.add('fred'); // Then ((fflib_MyList.IList) mocks.verify(mockList, mocks.atMost(5))).add(fflib_Match.anyString()); } @isTest private static void thatVerifiesAtMostSameNumberOfTimesWithMatchers() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); // When mockList.add('bob'); mockList.add('fred'); mockList.add('fred'); // Then ((fflib_MyList.IList) mocks.verify(mockList, mocks.atMost(3))).add(fflib_Match.anyString()); } @isTest private static void thatThrownExceptionIfCalledMoreThanAtMostNumberOfTimesWithMatchers() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); // When mockList.add('bob'); mockList.add('fred'); mockList.add('fred'); mockList.add('fred'); // Then try { ((fflib_MyList.IList) mocks.verify(mockList, mocks.atMost(3))).add(fflib_Match.anyString()); System.Assert.fail('an exception was expected because we are asserting that the method is called 3 times when instead is called four times'); } catch(fflib_ApexMocks.ApexMocksException ex) { System.Assert.areEqual('EXPECTED COUNT: 3 or fewer times' + '\nACTUAL COUNT: 4' + '\nMETHOD: fflib_MyList__sfdc_ApexStub.add(String)' + '\n---' + '\nACTUAL ARGS: ("bob"), ("fred"), ("fred"), ("fred")' + '\n---' + '\nEXPECTED ARGS: [any String]' , ex.getMessage(), 'Unexpected verify fail message'); } } /* * atLeastOnce */ @isTest private static void thatVerifiesAtLeastOnceNumberOfTimes() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); // When mockList.add('bob'); mockList.add('fred'); mockList.add('fred'); // Then ((fflib_MyList.IList) mocks.verify(mockList, mocks.atLeastOnce())).add('bob'); } @isTest private static void thatVerifiesAtLeastOnceNumberOfTimesWhenIsCalledMoreTimes() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); // When mockList.add('bob'); mockList.add('fred'); mockList.add('bob'); mockList.add('fred'); // Then ((fflib_MyList.IList) mocks.verify(mockList, mocks.atLeastOnce())).add('bob'); } @isTest private static void thatThrownExceptionIfCalledLessThanAtLeastOnceNumberOfTimes() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); // When mockList.add('rob'); mockList.add('fred'); // Then try { ((fflib_MyList.IList) mocks.verify(mockList, mocks.atLeastOnce())).add('bob'); System.Assert.fail('an exception was expected because we are asserting that the method is called at least once when instead is never called'); } catch(fflib_ApexMocks.ApexMocksException ex) { System.Assert.areEqual('EXPECTED COUNT: 1 or more times' + '\nACTUAL COUNT: 0' + '\nMETHOD: fflib_MyList__sfdc_ApexStub.add(String)' + '\n---' + '\nACTUAL ARGS: ("rob"), ("fred")' + '\n---' + '\nEXPECTED ARGS: "bob"', ex.getmessage(), 'Unexpected verify fail message'); } } @isTest private static void thatVerifiesAtLeastOnceNumberOfTimesWithMatchers() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); // When mockList.add('bob'); mockList.add('fred', 'fred', 'fred', 'fred'); // Then ((fflib_MyList.IList) mocks.verify(mockList, mocks.atLeastOnce())).add(fflib_Match.anyString()); } @isTest private static void thatVerifiesAtLeastOnceNumberOfTimesWhenIsCalledMoreTimesWithMatchers() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); // When mockList.add('bob'); mockList.add('fred', 'fred', 'fred', 'fred'); mockList.add('bob'); mockList.add('fred', 'fred', 'fred', 'fred'); mockList.add('bob'); mockList.add('fred', 'fred', 'fred', 'fred'); // Then ((fflib_MyList.IList) mocks.verify(mockList, mocks.atLeastOnce())).add(fflib_Match.anyString()); } @isTest private static void thatThrownExceptionIfCalledLessThanAtLeastOnceNumberOfTimesWithMatchers() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); // When mockList.add('fred', 'fred', 'fred', 'fred'); mockList.add('fred', 'fred', 'fred', 'fred'); mockList.add('fred', 'fred', 'fred', 'fred'); // Then try { ((fflib_MyList.IList) mocks.verify(mockList, mocks.atLeastOnce())).add(fflib_Match.anyString()); System.Assert.fail('an exception was expected because we are asserting that the method is called at lest once when instead is never called'); } catch(fflib_ApexMocks.ApexMocksException ex) { System.Assert.areEqual('EXPECTED COUNT: 1 or more times' + '\nACTUAL COUNT: 0' + '\nMETHOD: fflib_MyList__sfdc_ApexStub.add(String)' + '\n---' + '\nACTUAL ARGS: ()' + '\n---' + '\nEXPECTED ARGS: [any String]', ex.getMessage(), 'Unexpected verify fail message'); } } /* * between */ @isTest private static void thatVerifiesBetweenNumberOfTimes() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); // When mockList.add('bob'); mockList.add('fred'); mockList.add('bob'); mockList.add('fred'); mockList.add('bob'); mockList.add('fred'); mockList.add('bob'); mockList.add('fred'); // Then ((fflib_MyList.IList) mocks.verify(mockList, mocks.between(3, 5))).add('bob'); } @isTest private static void thatBetweenThrownExceptionIfCalledLessThanAtLeastNumberOfTimes() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); // When mockList.add('bob'); mockList.add('fred'); mockList.add('bob'); // Then try { ((fflib_MyList.IList) mocks.verify(mockList, mocks.between(3, 5))).add('bob'); System.Assert.fail('an exception was expected because we are asserting that the method is called at least 3 times when instead is called only twice'); } catch(fflib_ApexMocks.ApexMocksException ex) { System.Assert.areEqual('EXPECTED COUNT: 3 or more times' + '\nACTUAL COUNT: 2' + '\nMETHOD: fflib_MyList__sfdc_ApexStub.add(String)' + '\n---' + '\nACTUAL ARGS: ("bob"), ("fred"), ("bob")' + '\n---' + '\nEXPECTED ARGS: "bob"', ex.getMessage() ); } } @isTest private static void thatVerifiesBetweenNumberOfTimesWithMatchers() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); // When mockList.add('bob'); mockList.add('fred'); mockList.add('fred'); mockList.add('bob'); // Then ((fflib_MyList.IList) mocks.verify(mockList, mocks.between(3, 5))).add(fflib_Match.anyString()); } @isTest private static void thatBetweenThrownExceptionIfCalledLessThanAtLeastNumberOfTimesWithMatchers() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); // When mockList.add('bob'); mockList.add('fred'); // Then try { ((fflib_MyList.IList) mocks.verify(mockList, mocks.between(3, 5))).add(fflib_Match.anyString()); System.Assert.fail('an exception was expected because we are asserting that the method is called 3 times when instead is called only twice'); } catch(fflib_ApexMocks.ApexMocksException ex) { System.Assert.areEqual('EXPECTED COUNT: 3 or more times' + '\nACTUAL COUNT: 2' + '\nMETHOD: fflib_MyList__sfdc_ApexStub.add(String)' + '\n---' + '\nACTUAL ARGS: ("bob"), ("fred")' + '\n---' + '\nEXPECTED ARGS: [any String]', ex.getMessage() ); } } @isTest private static void thatBetweenThrownExceptionIfCalledMoreThanAtMostNumberOfTimes() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); // When mockList.add('bob'); mockList.add('fred'); mockList.add('fred'); mockList.add('bob'); mockList.add('bob'); mockList.add('bob'); mockList.add('bob'); mockList.add('bob'); mockList.add('fred'); // Then try { ((fflib_MyList.IList) mocks.verify(mockList, mocks.between(3, 5))).add('bob'); System.Assert.fail('an exception was expected because we are asserting that the method is called at most 5 times when instead is called six times'); } catch(fflib_ApexMocks.ApexMocksException ex) { System.Assert.areEqual('EXPECTED COUNT: 5 or fewer times' + '\nACTUAL COUNT: 6' + '\nMETHOD: fflib_MyList__sfdc_ApexStub.add(String)' + '\n---' + '\nACTUAL ARGS: ("bob"), ("fred"), ("fred"), ("bob"), ("bob"), ("bob"), ("bob"), ("bob"), ("fred")' + '\n---' + '\nEXPECTED ARGS: "bob"', ex.getMessage() ); } } @isTest private static void thatBetweenThrownExceptionIfCalledMoreThanAtMostNumberOfTimesWithMatchers() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); // When mockList.add('bob'); mockList.add('fred'); mockList.add('bob'); mockList.add('fred'); mockList.add('fred'); mockList.add('fred'); // Then try { ((fflib_MyList.IList) mocks.verify(mockList, mocks.between(3, 5))).add(fflib_Match.anyString()); System.Assert.fail('an exception was expected because we are asserting that the method is called 5 times when instead is called six times'); } catch(fflib_ApexMocks.ApexMocksException ex) { System.Assert.areEqual('EXPECTED COUNT: 5 or fewer times' + '\nACTUAL COUNT: 6' + '\nMETHOD: fflib_MyList__sfdc_ApexStub.add(String)' + '\n---' + '\nACTUAL ARGS: ("bob"), ("fred"), ("bob"), ("fred"), ("fred"), ("fred")' + '\n---' + '\nEXPECTED ARGS: [any String]', ex.getMessage(), 'Unexpected verify fail message'); } } /* * never */ @isTest private static void verifyNeverMethodHasNotBeenCalled() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); // When mockList.add('bob1'); mockList.add('bob2'); mockList.add('bob3'); // Then ((fflib_MyList.IList) mocks.verify(mockList, mocks.never())).add('bob'); } @isTest private static void verifyNeverMethodHasBeenNotCalledWithMatchers() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); // When mockList.add('fred', 'fred', 'fred', 'fred'); mockList.add('fred', 'fred', 'fred', 'fred'); mockList.add('fred', 'fred', 'fred', 'fred'); // Then ((fflib_MyList.IList) mocks.verify(mockList, mocks.never())).add(fflib_Match.anyString()); } @isTest private static void thatVerifyNeverFailsWhenCalledMoreTimes() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); // When mockList.add('bob'); mockList.add('bob'); // Then try { ((fflib_MyList.IList) mocks.verify(mockList, mocks.never())).add('bob'); System.Assert.fail('an exception was expected'); } catch(Exception exc) { assertFailMessage(exc.getMessage(), 0, 2); } } @isTest private static void thatVerifyNeverFailsWhenCalledMoreTimesWithMatchers() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); // When mockList.add('bob'); mockList.add('bob'); mockList.add('bob'); // Then try { ((fflib_MyList.IList) mocks.verify(mockList, mocks.never())).add(fflib_Match.anyString()); System.Assert.fail('an exception was expected'); } catch(Exception exc) { assertFailMessage(exc.getMessage(), 0, 3); } } /* * atLeastOnce */ @isTest private static void thatVerifiesAtLeastOnce() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); // When mockList.add('bob'); mockList.add('fred'); mockList.add('bob'); mockList.add('bob'); // Then ((fflib_MyList.IList) mocks.verify(mockList, mocks.atLeastOnce())).add('bob'); } @isTest private static void thatVerifiesAtLeastOnceWhenIsCalledMoreTimes() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); // When mockList.add('bob'); mockList.add('fred'); mockList.add('bob'); mockList.add('fred'); mockList.add('bob'); mockList.add('fred'); // Then ((fflib_MyList.IList) mocks.verify(mockList, mocks.atLeastOnce())).add('bob'); } @isTest private static void thatThrownExceptionIfCalledLessThanAtLeastOnce() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); // When mockList.add('bob'); mockList.add('fred'); mockList.add('bob'); // Then try { ((fflib_MyList.IList) mocks.verify(mockList, mocks.atLeastOnce())).add('rob'); System.Assert.fail('an exception was expected because we are asserting that the method is called one times when instead is not called'); } catch(fflib_ApexMocks.ApexMocksException ex) { System.Assert.areEqual('EXPECTED COUNT: 1 or more times' + '\nACTUAL COUNT: 0' + '\nMETHOD: fflib_MyList__sfdc_ApexStub.add(String)' + '\n---' + '\nACTUAL ARGS: ("bob"), ("fred"), ("bob")' + '\n---' + '\nEXPECTED ARGS: "rob"', ex.getMessage(), 'Unexpected verify fail message'); } } @isTest private static void thatVerifiesAtLeastOnceWithMatchers() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); // When mockList.add('bob'); mockList.add('fred'); // Then ((fflib_MyList.IList) mocks.verify(mockList, mocks.atLeastOnce())).add(fflib_Match.anyString()); } @isTest private static void thatVerifiesAtLeastOnceWhenIsCalledMoreTimesWithMatchers() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); // When mockList.add('bob'); mockList.add('fred'); mockList.add('fred'); mockList.add('fred'); // Then ((fflib_MyList.IList) mocks.verify(mockList, mocks.atLeastOnce())).add(fflib_Match.anyString()); } @isTest private static void thatThrownExceptionIfCalledLessThanAtLeastOnceWithMatchers() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); // When mockList.add('bob'); mockList.add('fred'); // Then try { ((fflib_MyList.IList) mocks.verify(mockList, mocks.atLeastOnce())).add(fflib_Match.stringStartsWith('rob')); System.Assert.fail('an exception was expected because we are asserting that the method is called once when instead is not called'); } catch(fflib_ApexMocks.ApexMocksException ex) { System.Assert.areEqual('EXPECTED COUNT: 1 or more times' + '\nACTUAL COUNT: 0' + '\nMETHOD: fflib_MyList__sfdc_ApexStub.add(String)' + '\n---' + '\nACTUAL ARGS: ("bob"), ("fred")' + '\n---' + '\nEXPECTED ARGS: [starts with "rob"]', ex.getMessage(), 'Unexpected verify fail message'); } } /* * HELPER METHODS */ private static void assertFailMessage(String exceptionMessage, Integer expectedInvocations, Integer actualsInvocations) { System.Assert.isTrue( exceptionMessage.startsWith('EXPECTED COUNT: ' + expectedInvocations + '\nACTUAL COUNT: ' + actualsInvocations), 'Unexpected verify fail message: ' + exceptionMessage ); } /* * HELPER CLASSES */ private class isOdd implements fflib_IMatcher { public Boolean matches(Object arg) { return arg instanceof Integer ? Math.mod((Integer)arg, 2) == 1: false; } } private class isEven implements fflib_IMatcher { public Boolean matches(Object arg) { return arg instanceof Integer ? Math.mod((Integer)arg, 2) == 0: false; } } } ================================================ FILE: sfdx-source/apex-mocks/test/classes/fflib_AnyOrderTest.cls-meta.xml ================================================ 63.0 Active ================================================ FILE: sfdx-source/apex-mocks/test/classes/fflib_ApexMocksTest.cls ================================================ /* * Copyright (c) 2014-2017 FinancialForce.com, inc. All rights reserved. */ @isTest private class fflib_ApexMocksTest { private static final fflib_ApexMocks MY_MOCKS = new fflib_ApexMocks(); private static final fflib_MyList MY_MOCK_LIST = (fflib_MyList)MY_MOCKS.mock(fflib_MyList.class); @isTest static void whenStubMultipleCallsWithMatchersShouldReturnExpectedValues() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); mocks.startStubbing(); mocks.when(mockList.get2(fflib_Match.anyInteger(), fflib_Match.anyString())).thenReturn('any'); mocks.when(mockList.get2(fflib_Match.anyInteger(), fflib_Match.stringContains('Hello'))).thenReturn('hello'); mocks.stopStubbing(); // When String actualValue = mockList.get2(0, 'Hi hi Hello Hi hi'); // Then System.Assert.areEqual('hello', actualValue); } @isTest static void whenVerifyMultipleCallsWithMatchersShouldReturnCorrectMethodCallCounts() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); // When mockList.add('bob'); mockList.add('fred'); // Then ((fflib_MyList.IList) mocks.verify(mockList, 2)).add(fflib_Match.anyString()); ((fflib_MyList.IList) mocks.verify(mockList)).add('fred'); ((fflib_MyList.IList) mocks.verify(mockList)).add(fflib_Match.stringContains('fred')); } @isTest static void whenStubExceptionWithMatchersShouldThrowException() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); mocks.startStubbing(); ((fflib_MyList.IList) mocks.doThrowWhen(new MyException('Matcher Exception'), mockList)).add(fflib_Match.stringContains('Hello')); mocks.stopStubbing(); // When mockList.add('Hi'); try { mockList.add('Hi Hello Hi'); System.Assert.fail('Expected exception'); } catch (MyException e) { //Then System.Assert.areEqual('Matcher Exception', e.getMessage()); } } @isTest static void whenVerifyWithCombinedMatchersShouldReturnCorrectMethodCallCounts() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); // When mockList.add('bob'); mockList.add('fred'); // Then ((fflib_MyList.IList) mocks.verify(mockList, 0)).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, 2)).add( (String)fflib_Match.anyOf(fflib_Match.eq('bob'), fflib_Match.eq('fred')) ); ((fflib_MyList.IList) mocks.verify(mockList, 1)).add( (String)fflib_Match.anyOf(fflib_Match.eq('bob'), fflib_Match.eq('jack')) ); ((fflib_MyList.IList) mocks.verify(mockList, 2)).add( (String)fflib_Match.noneOf(fflib_Match.eq('jack'), fflib_Match.eq('tim')) ); ((fflib_MyList.IList) mocks.verify(mockList, 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, 2)).add( (String)fflib_Match.isNot(fflib_Match.eq('jack')) ); } @isTest static void whenStubCustomMatchersCanBeUsed() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); mocks.startStubbing(); mocks.when(mockList.get((Integer)fflib_Match.matches(new isOdd()))).thenReturn('Odd'); mocks.when(mockList.get((Integer)fflib_Match.matches(new isEven()))).thenReturn('Even'); mocks.stopStubbing(); // When String s1 = mockList.get(1); String s2 = mockList.get(2); String s3 = mockList.get(3); String s4 = mockList.get(4); String s5 = mockList.get(5); // Then System.Assert.areEqual('Odd', s1); System.Assert.areEqual('Even', s2); System.Assert.areEqual('Odd', s3); System.Assert.areEqual('Even', s4); System.Assert.areEqual('Odd', s5); } @isTest static void whenVerifyCustomMatchersCanBeUsed() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); // When mockList.get(1); mockList.get(2); mockList.get(3); mockList.get(4); mockList.get(5); // Then ((fflib_MyList.IList) mocks.verify(mockList, 3)).get((Integer)fflib_Match.matches(new isOdd())); ((fflib_MyList.IList) mocks.verify(mockList, 2)).get((Integer)fflib_Match.matches(new isEven())); } @isTest static void whenStubWithMatcherAndNonMatcherArgumentsShouldThrowException() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); String expectedError = 'The number of matchers defined (1).' + ' does not match the number expected (2)\n' + 'If you are using matchers all arguments must be passed in as matchers.\n' + 'For example myList.add(fflib_Match.anyInteger(), \'String\') should be defined as myList.add(fflib_Match.anyInteger(), fflib_Match.eq(\'String\')).'; // Then try { mocks.startStubbing(); mocks.when(mockList.get2(fflib_Match.anyInteger(), 'String literal')).thenReturn('fail'); System.Assert.fail('Expected exception'); } catch (fflib_ApexMocks.ApexMocksException e) { System.Assert.areEqual(expectedError, e.getMessage()); } } @isTest static void whenVerifyWithMatcherAndNonMatcherArgumentsShouldThrowException() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); String expectedError = 'The number of matchers defined (1).' + ' does not match the number expected (2)\n' + 'If you are using matchers all arguments must be passed in as matchers.\n' + 'For example myList.add(fflib_Match.anyInteger(), \'String\') should be defined as myList.add(fflib_Match.anyInteger(), fflib_Match.eq(\'String\')).'; mockList.get2(1, 'String literal'); // Then try { ((fflib_MyList.IList) mocks.verify(mockList)).get2(fflib_Match.anyInteger(), 'String literal'); System.Assert.fail('Expected exception'); } catch (fflib_ApexMocks.ApexMocksException e) { System.Assert.areEqual(expectedError, e.getMessage()); } } @isTest static void whenStubSameMethodWithMatchersAndNonMatchersShouldStubInOrder() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); mocks.startStubbing(); mocks.when(mockList.get2(1, 'Non-matcher first')).thenReturn('Bad'); //Set the return value using the non-matcher arguments mocks.when(mockList.get2(fflib_Match.eqInteger(1), fflib_Match.stringContains('Non-matcher first'))).thenReturn('Good'); //Override the return value using matcher arguments mocks.when(mockList.get2(fflib_Match.eqInteger(1), fflib_Match.stringContains('Matcher first'))).thenReturn('Bad'); //Set the return value using the matcher arguments mocks.when(mockList.get2(1, 'Matcher first')).thenReturn('Good'); //Override the return value using non-matcher arguments mocks.stopStubbing(); // When/Thens System.Assert.areEqual('Good', mockList.get2(1, 'Non-matcher first')); System.Assert.areEqual('Good', mockList.get2(1, 'Matcher first')); } @isTest static void whenStubExceptionSameMethodWithMatchersAndNonMatchersShouldStubInOrder() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); mocks.startStubbing(); ((fflib_MyList.IList)mocks.doThrowWhen(new fflib_ApexMocks.ApexMocksException('Bad'), mockList)).add('Non-matcher first'); //Set the exception value using the non-matcher arguments ((fflib_MyList.IList)mocks.doThrowWhen(new fflib_ApexMocks.ApexMocksException('Good'), mockList)).add(fflib_Match.stringContains('Non-matcher first')); //Override the exception value using matcher arguments ((fflib_MyList.IList)mocks.doThrowWhen(new fflib_ApexMocks.ApexMocksException('Bad'), mockList)).add(fflib_Match.stringContains('Matcher first')); //Set the exception value using the matcher arguments ((fflib_MyList.IList)mocks.doThrowWhen(new fflib_ApexMocks.ApexMocksException('Good'), mockList)).add('Matcher first'); //Override the exception value using non-matcher arguments mocks.stopStubbing(); // When/Thens try { mockList.add('Non-matcher first'); System.Assert.fail('Expected exception'); } catch (fflib_ApexMocks.ApexMocksException e) { System.Assert.areEqual('Good', e.getMessage()); } try { mockList.add('Matcher first'); System.Assert.fail('Expected exception'); } catch (fflib_ApexMocks.ApexMocksException e) { System.Assert.areEqual('Good', e.getMessage()); } } @isTest static void whenStubSingleCallWithSingleArgumentShouldReturnStubbedValue() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); mocks.startStubbing(); mocks.when(mockList.get(0)).thenReturn('bob'); mocks.stopStubbing(); // When String actualValue = mockList.get(0); // Then System.Assert.areEqual('bob', actualValue); } @isTest static void whenStubSingleCallWithNullReturnValueItShouldReturnNull() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); mocks.startStubbing(); mocks.when(mockList.get(0)).thenReturn(null); mocks.stopStubbing(); // When String actualValue = mockList.get(0); // Then System.Assert.areEqual(null, actualValue); } @isTest static void whenStubMultipleCallsWithSingleArgumentShouldReturnStubbedValues() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); mocks.startStubbing(); mocks.when(mockList.get(0)).thenReturn('bob'); mocks.when(mockList.get(1)).thenReturn('fred'); mocks.stopStubbing(); // When String actualValueArg0 = mockList.get(0); String actualValueArg1 = mockList.get(1); String actualValueArg2 = mockList.get(2); // Then System.Assert.areEqual('bob', actualValueArg0); System.Assert.areEqual('fred', actualValueArg1); System.Assert.areEqual(null, actualValueArg2); } @isTest static void whenStubSameCallWithDifferentArgumentValueShouldReturnLastStubbedValue() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); mocks.startStubbing(); mocks.when(mockList.get(0)).thenReturn('bob1'); mocks.when(mockList.get(0)).thenReturn('bob2'); mocks.stopStubbing(); // When String actualValue = mockList.get(0); // Then System.Assert.areEqual('bob2', actualValue); } @isTest static void whenStubCallWithNoArgumentsShouldReturnStubbedValue() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); mocks.startStubbing(); mocks.when(mockList.isEmpty()).thenReturn(false); mocks.stopStubbing(); // When Boolean actualValue = mockList.isEmpty(); // Then System.Assert.areEqual(false, actualValue); } @isTest static void verifySingleMethodCallWithNoArguments() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); // When mockList.isEmpty(); // Then ((fflib_MyList.IList) mocks.verify(mockList)).isEmpty(); } @isTest static void verifySingleMethodCallWithSingleArgument() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); // When mockList.add('bob'); // Then ((fflib_MyList.IList) mocks.verify(mockList)).add('bob'); } @isTest static void verifyMultipleMethodCallsWithSameSingleArgument() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); // When mockList.add('bob'); mockList.add('bob'); // Then ((fflib_MyList.IList) mocks.verify(mockList, 2)).add('bob'); } @isTest static void verifyMultipleMethodCallsWithDifferentSingleArgument() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); // When mockList.add('bob'); mockList.add('fred'); // Then ((fflib_MyList.IList) mocks.verify(mockList)).add('bob'); ((fflib_MyList.IList) mocks.verify(mockList)).add('fred'); } @isTest static void verifyMethodCallsWithSameNameButDifferentArgumentTypes() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); // When mockList.add('bob'); mockList.add(new String[] {'bob'}); mockList.add((String)null); mockList.add((String[])null); // Then ((fflib_MyList.IList) mocks.verify(mockList)).add('bob'); ((fflib_MyList.IList) mocks.verify(mockList)).add(new String[] {'bob'}); ((fflib_MyList.IList) mocks.verify(mockList)).add((String)null); ((fflib_MyList.IList) mocks.verify(mockList)).add((String[])null); } @isTest static void verifyMethodNotCalled() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); // When mockList.get(0); // Then ((fflib_MyList.IList) mocks.verify(mockList, fflib_ApexMocks.NEVER)).add('bob'); ((fflib_MyList.IList) mocks.verify(mockList)).get(0); } @isTest static void stubAndVerifyMethodCallsWithNoArguments() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); mocks.startStubbing(); mocks.when(mockList.isEmpty()).thenReturn(false); mocks.stopStubbing(); mockList.clear(); // When Boolean actualValue = mockList.isEmpty(); // Then System.Assert.areEqual(false, actualValue); ((fflib_MyList.IList) mocks.verify(mockList)).clear(); } @isTest static void whenStubExceptionTheExceptionShouldBeThrown() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); mocks.startStubbing(); mocks.when(mockList.get(0)).thenThrow(new MyException('Stubbed exception.')); mocks.stopStubbing(); // When try { mockList.get(0); System.Assert.fail('Stubbed exception should have been thrown.'); } catch(Exception e) { // Then System.Assert.isInstanceOfType(e, MyException.class); System.Assert.areEqual('Stubbed exception.', e.getMessage()); } } @isTest static void whenStubVoidMethodWithExceptionThenExceptionShouldBeThrown() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); mocks.startStubbing(); ((fflib_MyList.IList) mocks.doThrowWhen(new MyException('Stubbed exception.'), mockList)).clear(); mocks.stopStubbing(); // When try { mockList.clear(); System.Assert.fail('Stubbed exception should have been thrown.'); } catch(Exception e) { // Then System.Assert.isInstanceOfType(e, MyException.class); System.Assert.areEqual('Stubbed exception.', e.getMessage()); } } @isTest static void whenStubMultipleVoidMethodsWithExceptionsThenExceptionsShouldBeThrown() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); mocks.startStubbing(); ((fflib_MyList.IList) mocks.doThrowWhen(new MyException('clear stubbed exception.'), mockList)).clear(); ((fflib_MyList.IList) mocks.doThrowWhen(new MyException('add stubbed exception.'), mockList)).add('bob'); mocks.stopStubbing(); // When try { mockList.clear(); System.Assert.fail('Stubbed exception should have been thrown.'); } catch(Exception e) { // Then System.Assert.isInstanceOfType(e, MyException.class); System.Assert.areEqual('clear stubbed exception.', e.getMessage()); } // When try { mockList.add('bob'); System.Assert.fail('Stubbed exception should have been thrown.'); } catch(Exception e) { // Then System.Assert.isInstanceOfType(e, MyException.class); System.Assert.areEqual('add stubbed exception.', e.getMessage()); } } @isTest static void whenStubVoidMethodWithExceptionAndCallMethodTwiceThenExceptionShouldBeThrownTwice() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); mocks.startStubbing(); ((fflib_MyList.IList) mocks.doThrowWhen(new MyException('clear stubbed exception.'), mockList)).clear(); mocks.stopStubbing(); // When try { mockList.clear(); System.Assert.fail('Stubbed exception should have been thrown.'); } catch(Exception e) { // Then System.Assert.isInstanceOfType(e, MyException.class); System.Assert.areEqual('clear stubbed exception.', e.getMessage()); } // When try { mockList.clear(); System.Assert.fail('Stubbed exception should have been thrown.'); } catch(Exception e) { // Then System.Assert.isInstanceOfType(e, MyException.class); System.Assert.areEqual('clear stubbed exception.', e.getMessage()); } } @isTest static void verifyMethodCallWhenNoCallsBeenMadeForType() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); // Then ((fflib_MyList.IList) mocks.verify(mockList, fflib_ApexMocks.NEVER)).add('bob'); } @isTest static void verifySingleMethodCallWithMultipleArguments() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); // When mockList.set(0, 'bob'); // Then ((fflib_MyList.IList) mocks.verify(mockList)).set(0, 'bob'); ((fflib_MyList.IList) mocks.verify(mockList, fflib_ApexMocks.NEVER)).set(0, 'fred'); } @isTest static void whenStubMultipleCallsWithMultipleArgumentShouldReturnStubbedValues() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); mocks.startStubbing(); mocks.when(mockList.get2(0, 'zero')).thenReturn('bob'); mocks.when(mockList.get2(1, 'one')).thenReturn('fred'); mocks.when(mockList.get2(0, 'two')).thenReturn('bob'); mocks.when(mockList.get2(1, 'three')).thenReturn('bub'); mocks.stopStubbing(); // When String actualValueArg0 = mockList.get2(0, 'zero'); String actualValueArg1 = mockList.get2(1, 'one'); String actualValueArg2 = mockList.get2(0, 'two'); String actualValueArg3 = mockList.get2(1, 'three'); String actualValueArg4 = mockList.get2(0, 'three'); // Then System.Assert.areEqual('bob', actualValueArg0); System.Assert.areEqual('fred', actualValueArg1); System.Assert.areEqual('bob', actualValueArg2); System.Assert.areEqual('bub', actualValueArg3); System.Assert.areEqual(null, actualValueArg4); } @isTest static void whenStubNullConcreteArgValueCorrectValueIsReturned() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); String expected = 'hello'; mocks.startStubbing(); mocks.when(mockList.get(null)).thenReturn(expected); mocks.stopStubbing(); // When String actual = mockList.get(null); // Then System.Assert.areEqual(expected, actual); } @isTest static void whenSetDoThrowWhenExceptionsValuesAreSet() { //Given MyException e = new MyException('Test'); fflib_ApexMocks mocks = new fflib_ApexMocks(); List expsList = new List{e}; //When mocks.DoThrowWhenExceptions = expsList; //Then System.Assert.areEqual(expsList, mocks.DoThrowWhenExceptions); } @isTest static void whenVerifyMethodNeverCalledMatchersAreReset() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); // When mockList.add('bob'); // Then ((fflib_MyList.IList) mocks.verify(mockList, fflib_ApexMocks.NEVER)).get(fflib_Match.anyInteger()); ((fflib_MyList.IList) mocks.verify(mockList)).add(fflib_Match.anyString()); } @isTest static void whenMockIsGeneratedCanVerify() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); // When mockList.add('bob'); // Then ((fflib_MyList.IList) mocks.verify(mockList, fflib_ApexMocks.NEVER)).get(fflib_Match.anyInteger()); ((fflib_MyList.IList) mocks.verify(mockList)).add('bob'); } @isTest static void whenMockIsGeneratedCanStubVerify() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); // When mocks.startStubbing(); mocks.when(mockList.get(1)).thenReturn('One'); mocks.when(mockList.get(fflib_Match.integerMoreThan(2))).thenReturn('>Two'); mocks.stopStubbing(); // Then System.Assert.areEqual(null, mockList.get(0)); System.Assert.areEqual('One', mockList.get(1)); System.Assert.areEqual(null, mockList.get(2)); System.Assert.areEqual('>Two', mockList.get(3)); } @isTest static void whenMockVoidMethodRecordsCallCanVerify() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); // When mocks.mockVoidMethod( mockList, 'clear', new List(), new List() ); // Then ((fflib_MyList.IList) mocks.verify(mockList, 1)).clear(); } @isTest static void thatMultipleInstancesCanBeMockedIndependently() { fflib_ApexMocksConfig.HasIndependentMocks = true; // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList first = (fflib_MyList)mocks.mock(fflib_MyList.class); fflib_MyList second = (fflib_MyList)mocks.mock(fflib_MyList.class); mocks.startStubbing(); mocks.when(first.get(0)).thenReturn('First'); mocks.when(second.get(0)).thenReturn('Second'); mocks.stopStubbing(); // When String actual = first.get(0); // Then System.Assert.areEqual('First', actual, 'Should have returned stubbed value'); ((fflib_MyList)mocks.verify(first)).get(0); ((fflib_MyList)mocks.verify(second, mocks.never())).get(0); } @isTest static void thatMultipleInstancesCanBeMockedDependently() { fflib_ApexMocksConfig.HasIndependentMocks = false; // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList first = (fflib_MyList)mocks.mock(fflib_MyList.class); fflib_MyList second = (fflib_MyList)mocks.mock(fflib_MyList.class); mocks.startStubbing(); mocks.when(first.get(0)).thenReturn('First'); mocks.when(second.get(0)).thenReturn('Second'); mocks.stopStubbing(); // When String actual = first.get(0); // Then System.Assert.areEqual('Second', actual, 'Should have returned stubbed value'); ((fflib_MyList)mocks.verify(first)).get(0); ((fflib_MyList)mocks.verify(second)).get(0); } static void thatStubbingCanBeChainedFirstExceptionThenValue() { // Given // When MY_MOCKS.startStubbing(); MY_MOCKS.when(MY_MOCK_LIST.get(1)).thenThrow(new MyException('Stubbed exception.')).thenReturn('One'); MY_MOCKS.stopStubbing(); // Then assertExceptionMessage('Stubbed exception.'); assertReturnedValue('One'); } @isTest static void thatStubbingCanBeChainedFirstValueThenException() { // Given // When MY_MOCKS.startStubbing(); MY_MOCKS.when(MY_MOCK_LIST.get(1)).thenReturn('One').thenThrow(new MyException('Stubbed exception.')); MY_MOCKS.stopStubbing(); // Then assertReturnedValue('One'); assertExceptionMessage('Stubbed exception.'); } @isTest static void thatStubbingMultipleMethodsCanBeChainedFirstExceptionThenValue() { // Given // When MY_MOCKS.startStubbing(); MY_MOCKS.when(MY_MOCK_LIST.get(1)).thenThrow(new MyException('Stubbed exception.')).thenReturn('One'); MY_MOCKS.when(MY_MOCK_LIST.get2(2, 'Hello.')).thenThrow(new MyException('Stubbed exception2.')).thenReturn('One2'); MY_MOCKS.stopStubbing(); // Then assertExceptionMessage('Stubbed exception.'); assertReturnedValue('One'); assertExceptionMessageForGet2('Stubbed exception2.'); assertReturnedValueForGet2('One2'); } @isTest static void thatStubbingMultipleMethodsCanBeChainedFirstValueThenException() { // Given // When MY_MOCKS.startStubbing(); MY_MOCKS.when(MY_MOCK_LIST.get(1)).thenReturn('One').thenThrow(new MyException('Stubbed exception.')); MY_MOCKS.when(MY_MOCK_LIST.get2(2, 'Hello.')).thenReturn('One2').thenThrow(new MyException('Stubbed exception2.')); MY_MOCKS.stopStubbing(); // Then assertReturnedValue('One'); assertExceptionMessage('Stubbed exception.'); assertReturnedValueForGet2('One2'); assertExceptionMessageForGet2('Stubbed exception2.'); } @isTest static void thatStubbingReturnsDifferentValuesForDifferentCalls() { // Given // When MY_MOCKS.startStubbing(); MY_MOCKS.when(MY_MOCK_LIST.get(1)).thenReturnMulti(new List{'One', 'Two', 'Three'}); MY_MOCKS.stopStubbing(); // Then assertReturnedValue('One'); assertReturnedValue('Two'); assertReturnedValue('Three'); } @isTest static void thatStubbingReturnsDifferentValuesForDifferentCallsAndRepeatLastValuesForFurtherCalls() { // Given // When MY_MOCKS.startStubbing(); MY_MOCKS.when(MY_MOCK_LIST.get(1)).thenReturnMulti(new List{'One', 'Two', 'Three'}); MY_MOCKS.stopStubbing(); // Then assertReturnedValue('One'); assertReturnedValue('Two'); assertReturnedValue('Three'); assertReturnedValue('Three'); assertReturnedValue('Three'); } @isTest static void thatStubbingThrowsDifferentExceptionsForDifferentCalls() { // Given MyException first = new MyException('first.'); MyException second = new MyException('second.'); MyException third = new MyException('third.'); // When MY_MOCKS.startStubbing(); MY_MOCKS.when(MY_MOCK_LIST.get(1)).thenThrowMulti(new List{first, second, third}); MY_MOCKS.stopStubbing(); // Then assertExceptionMessage('first.'); assertExceptionMessage('second.'); assertExceptionMessage('third.'); } @isTest static void thatStubbingThrowsDifferentExceptionsForDifferentCallsAndRepeatLastExceptionForFurtherCalls() { // Given MyException first = new MyException('first.'); MyException second = new MyException('second.'); MyException third = new MyException('third.'); // When MY_MOCKS.startStubbing(); MY_MOCKS.when(MY_MOCK_LIST.get(1)).thenThrowMulti(new List{first, second, third}); MY_MOCKS.stopStubbing(); // Then assertExceptionMessage('first.'); assertExceptionMessage('second.'); assertExceptionMessage('third.'); assertExceptionMessage('third.'); assertExceptionMessage('third.'); } @isTest static void thatStubbingThrowsAndReturnsDifferentExceptionsAndValuesForDifferentCalls() { // Given MyException first = new MyException('first.'); MyException second = new MyException('second.'); MyException third = new MyException('third.'); // When MY_MOCKS.startStubbing(); MY_MOCKS.when(MY_MOCK_LIST.get(1)). thenThrowMulti(new List{first, second, third}). thenReturnMulti(new List{'One', 'Two', 'Three'}); MY_MOCKS.stopStubbing(); // Then assertExceptionMessage('first.'); assertExceptionMessage('second.'); assertExceptionMessage('third.'); assertReturnedValue('One'); assertReturnedValue('Two'); assertReturnedValue('Three'); assertReturnedValue('Three'); assertReturnedValue('Three'); } @isTest static void thatStubbingReturnsAndThrowsDifferentValuesAndExceptionsForDifferentCalls() { // Given MyException first = new MyException('first.'); MyException second = new MyException('second.'); MyException third = new MyException('third.'); // When MY_MOCKS.startStubbing(); MY_MOCKS.when(MY_MOCK_LIST.get(1)). thenReturnMulti(new List{'One', 'Two', 'Three'}). thenThrowMulti(new List{first, second, third}); MY_MOCKS.stopStubbing(); // Then assertReturnedValue('One'); assertReturnedValue('Two'); assertReturnedValue('Three'); assertExceptionMessage('first.'); assertExceptionMessage('second.'); assertExceptionMessage('third.'); assertExceptionMessage('third.'); assertExceptionMessage('third.'); } @isTest static void thatStubbingMultipleTimesOverridePreviousThenReturnWithSingleValue() { // Given // When MY_MOCKS.startStubbing(); MY_MOCKS.when(MY_MOCK_LIST.get(1)).thenReturn('One'); MY_MOCKS.when(MY_MOCK_LIST.get(1)).thenReturn('Two'); MY_MOCKS.stopStubbing(); // Then assertReturnedValue('Two'); assertReturnedValue('Two'); } @isTest static void thatStubbingMultipleTimesOverridePreviousThenReturnMultiWithSingleValue() { // Given // When MY_MOCKS.startStubbing(); MY_MOCKS.when(MY_MOCK_LIST.get(1)).thenReturnMulti(new List{'One', 'Two', 'Three'}); MY_MOCKS.when(MY_MOCK_LIST.get(1)).thenReturn('Two'); MY_MOCKS.stopStubbing(); // Then assertReturnedValue('Two'); assertReturnedValue('Two'); } @isTest static void thatStubbingMultipleTimesOverridePreviousThenReturnMultiWithMultiValue() { // Given // When MY_MOCKS.startStubbing(); MY_MOCKS.when(MY_MOCK_LIST.get(1)).thenReturnMulti(new List{'One', 'Two', 'Three'}); MY_MOCKS.when(MY_MOCK_LIST.get(1)).thenReturnMulti(new List{'Four', 'Five', 'Six'}); MY_MOCKS.stopStubbing(); // Then assertReturnedValue('Four'); assertReturnedValue('Five'); assertReturnedValue('Six'); assertReturnedValue('Six'); assertReturnedValue('Six'); } @isTest static void thatStubbingMultipleTimesOverridePreviousThenReturnWithMultiValues() { // Given // When MY_MOCKS.startStubbing(); MY_MOCKS.when(MY_MOCK_LIST.get(1)).thenReturn('Two'); MY_MOCKS.when(MY_MOCK_LIST.get(1)).thenReturnMulti(new List{'One', 'Two', 'Three'}); MY_MOCKS.stopStubbing(); // Then assertReturnedValue('One'); assertReturnedValue('Two'); assertReturnedValue('Three'); assertReturnedValue('Three'); assertReturnedValue('Three'); } @isTest static void thatStubbingMultipleTimesOverridePreviousThenReturnMultiWithSingleException() { // Given MyException first = new MyException('first.'); // When MY_MOCKS.startStubbing(); MY_MOCKS.when(MY_MOCK_LIST.get(1)).thenReturnMulti(new List{'One', 'Two', 'Three'}); MY_MOCKS.when(MY_MOCK_LIST.get(1)).thenThrow(first); MY_MOCKS.stopStubbing(); // Then assertExceptionMessage('first.'); assertExceptionMessage('first.'); } @isTest static void thatStubbingMultipleTimesOverridePreviousThenReturnMultiWithMultiExceptions() { // Given MyException first = new MyException('first.'); MyException second = new MyException('second.'); MyException third = new MyException('third.'); // When MY_MOCKS.startStubbing(); MY_MOCKS.when(MY_MOCK_LIST.get(1)).thenReturnMulti(new List{'One', 'Two', 'Three'}); MY_MOCKS.when(MY_MOCK_LIST.get(1)).thenThrowMulti(new List{first, second, third}); MY_MOCKS.stopStubbing(); // Then assertExceptionMessage('first.'); assertExceptionMessage('second.'); assertExceptionMessage('third.'); assertExceptionMessage('third.'); assertExceptionMessage('third.'); } @isTest static void thatStubbingMultipleTimesOverridePreviousThenReturnWithMultiExceptions() { // Given MyException first = new MyException('first.'); MyException second = new MyException('second.'); MyException third = new MyException('third.'); // When MY_MOCKS.startStubbing(); MY_MOCKS.when(MY_MOCK_LIST.get(1)).thenReturn('Two'); MY_MOCKS.when(MY_MOCK_LIST.get(1)).thenThrowMulti(new List{first, second, third}); MY_MOCKS.stopStubbing(); // Then assertExceptionMessage('first.'); assertExceptionMessage('second.'); assertExceptionMessage('third.'); assertExceptionMessage('third.'); assertExceptionMessage('third.'); } @isTest static void thatStubbingMultipleTimesOverridePreviousThenReturnWithSingleException() { // Given MyException first = new MyException('first.'); // When MY_MOCKS.startStubbing(); MY_MOCKS.when(MY_MOCK_LIST.get(1)).thenReturn('Two'); MY_MOCKS.when(MY_MOCK_LIST.get(1)).thenThrow(first); MY_MOCKS.stopStubbing(); // Then assertExceptionMessage('first.'); assertExceptionMessage('first.'); } @isTest static void thatStubbingMultipleTimesOverridePreviousThenThrowWithSingleValue() { // Given MyException first = new MyException('first.'); // When MY_MOCKS.startStubbing(); MY_MOCKS.when(MY_MOCK_LIST.get(1)).thenThrow(first); MY_MOCKS.when(MY_MOCK_LIST.get(1)).thenReturn('Two'); MY_MOCKS.stopStubbing(); // Then assertReturnedValue('Two'); assertReturnedValue('Two'); } @isTest static void thatStubbingMultipleTimesOverridePreviousThenThrowMultiWithSingleValue() { // Given MyException first = new MyException('first.'); MyException second = new MyException('second.'); MyException third = new MyException('third.'); // When MY_MOCKS.startStubbing(); MY_MOCKS.when(MY_MOCK_LIST.get(1)).thenThrowMulti(new List{first, second, third}); MY_MOCKS.when(MY_MOCK_LIST.get(1)).thenReturn('Two'); MY_MOCKS.stopStubbing(); // Then assertReturnedValue('Two'); assertReturnedValue('Two'); } @isTest static void thatStubbingMultipleTimesOverridePreviousThenThrowMultiWithMultiValue() { // Given MyException first = new MyException('first.'); MyException second = new MyException('second.'); MyException third = new MyException('third.'); // When MY_MOCKS.startStubbing(); MY_MOCKS.when(MY_MOCK_LIST.get(1)).thenThrowMulti(new List{first, second, third}); MY_MOCKS.when(MY_MOCK_LIST.get(1)).thenReturnMulti(new List{'Four', 'Five', 'Six'}); MY_MOCKS.stopStubbing(); // Then assertReturnedValue('Four'); assertReturnedValue('Five'); assertReturnedValue('Six'); assertReturnedValue('Six'); assertReturnedValue('Six'); } @isTest static void thatStubbingMultipleTimesOverridePreviousThenThrowWithMultiValues() { // Given MyException first = new MyException('first.'); // When MY_MOCKS.startStubbing(); MY_MOCKS.when(MY_MOCK_LIST.get(1)).thenThrow(first); MY_MOCKS.when(MY_MOCK_LIST.get(1)).thenReturnMulti(new List{'One', 'Two', 'Three'}); MY_MOCKS.stopStubbing(); // Then assertReturnedValue('One'); assertReturnedValue('Two'); assertReturnedValue('Three'); assertReturnedValue('Three'); assertReturnedValue('Three'); } @isTest static void thatStubbingMultipleTimesOverridePreviousThenThrowMultiWithSingleException() { // Given MyException first = new MyException('first.'); MyException second = new MyException('second.'); MyException third = new MyException('third.'); MyException fourth = new MyException('fourth.'); // When MY_MOCKS.startStubbing(); MY_MOCKS.when(MY_MOCK_LIST.get(1)).thenThrowMulti(new List{first, second, third}); MY_MOCKS.when(MY_MOCK_LIST.get(1)).thenThrow(fourth); MY_MOCKS.stopStubbing(); // Then assertExceptionMessage('fourth.'); assertExceptionMessage('fourth.'); } @isTest static void thatStubbingMultipleTimesOverridePreviousThenThrowMultiWithMultiExceptions() { // Given MyException first = new MyException('first.'); MyException second = new MyException('second.'); MyException third = new MyException('third.'); MyException fourth = new MyException('fourth.'); MyException fifth = new MyException('fifth.'); MyException sixth = new MyException('sixth.'); // When MY_MOCKS.startStubbing(); MY_MOCKS.when(MY_MOCK_LIST.get(1)).thenThrowMulti(new List{first, second, third}); MY_MOCKS.when(MY_MOCK_LIST.get(1)).thenThrowMulti(new List{fourth, fifth, sixth}); MY_MOCKS.stopStubbing(); // Then assertExceptionMessage('fourth.'); assertExceptionMessage('fifth.'); assertExceptionMessage('sixth.'); assertExceptionMessage('sixth.'); assertExceptionMessage('sixth.'); } @isTest static void thatStubbingMultipleTimesOverridePreviousThenThrowWithMultiExceptions() { // Given MyException beforeFirst = new MyException('before first.'); MyException first = new MyException('first.'); MyException second = new MyException('second.'); MyException third = new MyException('third.'); // When MY_MOCKS.startStubbing(); MY_MOCKS.when(MY_MOCK_LIST.get(1)).thenThrow(beforeFirst); MY_MOCKS.when(MY_MOCK_LIST.get(1)).thenThrowMulti(new List{first, second, third}); MY_MOCKS.stopStubbing(); // Then assertExceptionMessage('first.'); assertExceptionMessage('second.'); assertExceptionMessage('third.'); assertExceptionMessage('third.'); assertExceptionMessage('third.'); } @isTest static void thatStubbingMultipleTimesOverridePreviousThenThrowWithSingleException() { // Given MyException beforeFirst = new MyException('before first.'); MyException first = new MyException('first.'); // When MY_MOCKS.startStubbing(); MY_MOCKS.when(MY_MOCK_LIST.get(1)).thenThrow(beforeFirst); MY_MOCKS.when(MY_MOCK_LIST.get(1)).thenThrow(first); MY_MOCKS.stopStubbing(); // Then assertExceptionMessage('first.'); assertExceptionMessage('first.'); } @isTest static void thatVoidMethodThrowsMultipleExceptions() { // Given MyException beforeFirst = new MyException('before first.'); MyException first = new MyException('first.'); MyException second = new MyException('second.'); MyException third = new MyException('third.'); // When MY_MOCKS.startStubbing(); ((fflib_MyList.IList) MY_MOCKS.doThrowWhen(new List{first, second, third}, MY_MOCK_LIST)).add('Hello'); MY_MOCKS.stopStubbing(); // Then assertExceptionMessageOnVoidMethod('first.'); assertExceptionMessageOnVoidMethod('second.'); assertExceptionMessageOnVoidMethod('third.'); assertExceptionMessageOnVoidMethod('third.'); assertExceptionMessageOnVoidMethod('third.'); } @isTest static void thatMultipleVoidMethodsThrowsMultipleExceptions() { // Given MyException first = new MyException('first.'); MyException second = new MyException('second.'); MyException third = new MyException('third.'); MyException first2 = new MyException('first2.'); MyException second2 = new MyException('second2.'); MyException third2 = new MyException('third2.'); // When MY_MOCKS.startStubbing(); ((fflib_MyList.IList) MY_MOCKS.doThrowWhen(new List{first2, second2, third2}, MY_MOCK_LIST)).addMore('Hello'); ((fflib_MyList.IList) MY_MOCKS.doThrowWhen(new List{first, second, third}, MY_MOCK_LIST)).add('Hello'); MY_MOCKS.stopStubbing(); // Then assertExceptionMessageOnVoidMethod('first.'); assertExceptionMessageOnVoidMethod('second.'); assertExceptionMessageOnVoidMethod('third.'); assertExceptionMessageOnVoidMethod('third.'); assertExceptionMessageOnVoidMethod('third.'); assertExceptionMessageOnAddMoreVoidMethod('first2.'); assertExceptionMessageOnAddMoreVoidMethod('second2.'); assertExceptionMessageOnAddMoreVoidMethod('third2.'); assertExceptionMessageOnAddMoreVoidMethod('third2.'); assertExceptionMessageOnAddMoreVoidMethod('third2.'); } @isTest static void thatStubbingMutipleTimesVoidMethodThrowsMultipleExceptionsOverride() { // Given MyException beforeFirst = new MyException('before first.'); MyException first = new MyException('first.'); MyException second = new MyException('second.'); MyException third = new MyException('third.'); MyException fourth = new MyException('fourth.'); MyException fifth = new MyException('fifth.'); MyException sixth = new MyException('sixth.'); // When MY_MOCKS.startStubbing(); ((fflib_MyList.IList) MY_MOCKS.doThrowWhen(new List{first, second, third}, MY_MOCK_LIST)).add('Hello'); ((fflib_MyList.IList) MY_MOCKS.doThrowWhen(new List{fourth, fifth, sixth}, MY_MOCK_LIST)).add('Hello'); MY_MOCKS.stopStubbing(); // Then assertExceptionMessageOnVoidMethod('fourth.'); assertExceptionMessageOnVoidMethod('fifth.'); assertExceptionMessageOnVoidMethod('sixth.'); assertExceptionMessageOnVoidMethod('sixth.'); assertExceptionMessageOnVoidMethod('sixth.'); } @isTest static void thatStubbingMutipleTimesVoidMethodThrowsMultipleExceptionsOverrideWithSingleException() { // Given MyException beforeFirst = new MyException('before first.'); MyException first = new MyException('first.'); MyException second = new MyException('second.'); MyException third = new MyException('third.'); MyException fourth = new MyException('fourth.'); MyException fifth = new MyException('fifth.'); MyException sixth = new MyException('sixth.'); // When MY_MOCKS.startStubbing(); ((fflib_MyList.IList) MY_MOCKS.doThrowWhen(new List{first, second, third}, MY_MOCK_LIST)).add('Hello'); ((fflib_MyList.IList) MY_MOCKS.doThrowWhen(fourth, MY_MOCK_LIST)).add('Hello'); MY_MOCKS.stopStubbing(); // Then assertExceptionMessageOnVoidMethod('fourth.'); assertExceptionMessageOnVoidMethod('fourth.'); } @isTest static void thatExceptionIsthrownWhenStubbingIsNotDone() { MY_MOCKS.startStubbing(); MY_MOCKS.when(MY_MOCK_LIST.get(1)); MY_MOCKS.stopStubbing(); try { MY_MOCK_LIST.get(1); System.Assert.fail('an exception was expected'); } catch(fflib_ApexMocks.ApexMocksException myex) { System.Assert.areEqual( 'The stubbing is not correct, no return values have been set.', myex.getMessage(), 'the message reported by the exception is not correct'); } } @isTest static void thatExceptionIsthrownWhenReturnMultiPassEmptyList() { try { MY_MOCKS.startStubbing(); MY_MOCKS.when(MY_MOCK_LIST.get(1)).thenReturnMulti(new List()); MY_MOCKS.stopStubbing(); System.Assert.fail('an exception was expected'); } catch(fflib_ApexMocks.ApexMocksException myex) { System.Assert.areEqual( 'The stubbing is not correct, no return values have been set.', myex.getMessage(), 'the message reported by the exception is not correct'); } } @isTest static void thatExceptionIsthrownWhenReturnMultiPassNullList() { try { MY_MOCKS.startStubbing(); MY_MOCKS.when(MY_MOCK_LIST.get(1)).thenReturnMulti(null); MY_MOCKS.stopStubbing(); System.Assert.fail('an exception was expected'); } catch(fflib_ApexMocks.ApexMocksException myex) { System.Assert.areEqual( 'The stubbing is not correct, no return values have been set.', myex.getMessage(), 'the message reported by the exception is not correct'); } } @isTest static void thatExceptionIsthrownWhenThrowMultiPassEmptyList() { try { MY_MOCKS.startStubbing(); MY_MOCKS.when(MY_MOCK_LIST.get(1)).thenThrowMulti(new List()); MY_MOCKS.stopStubbing(); System.Assert.fail('an exception was expected'); } catch(fflib_ApexMocks.ApexMocksException myex) { System.Assert.areEqual( 'The stubbing is not correct, no return values have been set.', myex.getMessage(), 'the message reported by the exception is not correct'); } } @isTest static void thatExceptionIsthrownWhenThrowMultiPassNullList() { try { MY_MOCKS.startStubbing(); MY_MOCKS.when(MY_MOCK_LIST.get(1)).thenThrowMulti(null); MY_MOCKS.stopStubbing(); System.Assert.fail('an exception was expected'); } catch(fflib_ApexMocks.ApexMocksException myex) { System.Assert.areEqual( 'The stubbing is not correct, no return values have been set.', myex.getMessage(), 'the message reported by the exception is not correct'); } } @isTest static void thatNullCanBeUsedAsReturnValue() { MY_MOCKS.startStubbing(); MY_MOCKS.when(MY_MOCK_LIST.get(1)).thenReturn(null); MY_MOCKS.stopStubbing(); System.Assert.areEqual(null, MY_MOCK_LIST.get(1), 'it should be possible stub using the null value'); } @isTest static void thatNullCanBeUsedAsExceptionvalue() { MY_MOCKS.startStubbing(); MY_MOCKS.when(MY_MOCK_LIST.get(1)).thenThrow(null); MY_MOCKS.stopStubbing(); System.Assert.areEqual(null, MY_MOCK_LIST.get(1), 'it should be possible stub using the null value'); } private static void assertExceptionMessage(String expectedMessage) { try { MY_MOCK_LIST.get(1); System.Assert.fail('an exception was expected'); } catch(MyException myex) { System.Assert.areEqual(expectedMessage, myex.getMessage(), 'the message reported by the exception is not correct'); } } private static void assertExceptionMessageForGet2(String expectedMessage) { try { MY_MOCK_LIST.get2(2, 'Hello.'); System.Assert.fail('an exception was expected'); } catch(MyException myex) { System.Assert.areEqual(expectedMessage, myex.getMessage(), 'the message reported by the exception is not correct'); } } private static void assertExceptionMessageOnVoidMethod(String expectedMessage) { try { MY_MOCK_LIST.add('Hello'); System.Assert.fail('an exception was expected'); } catch(MyException myex) { System.Assert.areEqual(expectedMessage, myex.getMessage(), 'the message reported by the exception is not correct'); } } private static void assertExceptionMessageOnAddMoreVoidMethod(String expectedMessage) { try { MY_MOCK_LIST.addMore('Hello'); System.Assert.fail('an exception was expected'); } catch(MyException myex) { System.Assert.areEqual(expectedMessage, myex.getMessage(), 'the message reported by the exception is not correct'); } } private static void assertReturnedValue(String expectedValue) { System.Assert.areEqual(expectedValue, MY_MOCK_LIST.get(1), 'the method did not returned the expected value'); } private static void assertReturnedValueForGet2(String expectedValue) { System.Assert.areEqual(expectedValue, MY_MOCK_LIST.get2(2, 'Hello.'), 'the method did not returned the expected value'); } @isTest static void thatToStringReturnsSimpleStringValue() { System.Assert.areEqual('fflib_ApexMocks', '' + new fflib_ApexMocks()); } private class MyException extends Exception { } private class isOdd implements fflib_IMatcher { public Boolean matches(Object arg) { return arg instanceof Integer ? Math.mod((Integer)arg, 2) == 1: false; } } private class isEven implements fflib_IMatcher { public Boolean matches(Object arg) { return arg instanceof Integer ? Math.mod((Integer)arg, 2) == 0: false; } } } ================================================ FILE: sfdx-source/apex-mocks/test/classes/fflib_ApexMocksTest.cls-meta.xml ================================================ 63.0 Active ================================================ FILE: sfdx-source/apex-mocks/test/classes/fflib_ApexMocksUtilsTest.cls ================================================ /** * Copyright (c) 2014-2016, FinancialForce.com, inc * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * - Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * - Neither the name of the FinancialForce.com, inc nor the names of its contributors * may be used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ @isTest public class fflib_ApexMocksUtilsTest { public static Schema.FieldSet findAnyFieldSet() { for (Schema.SObjectType objectType : Schema.getGlobalDescribe().values()) { for (Schema.FieldSet fs : objectType.getDescribe().FieldSets.getMap().values()) { return fs; } } return null; } @isTest private static void makeRelationship_returnsObjectsWithRelationFieldSet() { //Given Account acc = new Account( Id = fflib_IDGenerator.generate(Account.SObjectType), Name = 'AccName', NumberOfEmployees = 7 ); Contact contact1 = new Contact( Id = fflib_IDGenerator.generate(Contact.SObjectType), DoNotCall = true ); Contact contact2 = new Contact( Id = fflib_IDGenerator.generate(Contact.SObjectType), DoNotCall = false ); //When Account accWithRelationships = ((List)fflib_ApexMocksUtils.makeRelationship( List.class, new List { acc }, Contact.AccountId, new List> { new List { contact1, contact2 }} ))[0]; //Then System.Assert.areEqual(acc.Id, accWithRelationships.Id); System.Assert.areEqual(acc.Name, accWithRelationships.Name); System.Assert.areEqual(acc.NumberOfEmployees, accWithRelationships.NumberOfEmployees); //Assert relationship fields List contacts = accWithRelationships.Contacts; System.Assert.areNotEqual(null, contacts); System.Assert.areEqual(2, contacts.size()); System.Assert.areEqual(contact1.Id, contacts[0].Id); System.Assert.areEqual(contact1.DoNotCall, contacts[0].DoNotCall); System.Assert.areEqual(contact2.Id, contacts[1].Id); System.Assert.areEqual(contact2.DoNotCall, contacts[1].DoNotCall); } @isTest private static void makeRelationship_GenericOverload_ReturnsObjectsWithRelationFieldSet() { //Given SObject acc = Schema.getGlobalDescribe().get('Account').newSObject(); acc.put('Id', fflib_IDGenerator.generate(acc.getSObjectType())); acc.put('Name', 'AccName'); acc.put('NumberOfEmployees', 7); SObject contact1 = Schema.getGlobalDescribe().get('Contact').newSObject(); contact1.put('Id', fflib_IDGenerator.generate(contact1.getSObjectType())); contact1.put('DoNotCall', true); SObject contact2 = Schema.getGlobalDescribe().get('Contact').newSObject(); contact2.put('Id', fflib_IDGenerator.generate(contact2.getSObjectType())); contact2.put('DoNotCall', false); //When SObject accWithRelationships = ((List)fflib_ApexMocksUtils.makeRelationship( 'Account', 'Contact', new List { acc }, 'AccountId', new List> { new List { contact1, contact2 }} ))[0]; //Then System.Assert.areEqual(acc.Id, accWithRelationships.Id); System.Assert.areEqual(acc.get('Name'), accWithRelationships.get('Name')); System.Assert.areEqual(acc.get('NumberOfEmployees'), accWithRelationships.get('NumberOfEmployees')); //Assert relationship fields List contacts = accWithRelationships.getSObjects('Contacts'); System.Assert.areNotEqual(null, contacts); System.Assert.areEqual(2, contacts.size()); System.Assert.areEqual(contact1.Id, contacts[0].Id); System.Assert.areEqual((Boolean)contact1.get('DoNotCall'), (Boolean)contacts[0].get('DoNotCall')); System.Assert.areEqual(contact2.Id, contacts[1].Id); System.Assert.areEqual((Boolean)contact2.get('DoNotCall'), (Boolean)contacts[1].get('DoNotCall')); } @isTest private static void makeRelationship_GenericOverload_ThrowsErrorOnInvalidParentType() { // Setup parent object SObject acc = Schema.getGlobalDescribe().get('Account').newSObject(); acc.put('Id', fflib_IDGenerator.generate(acc.getSObjectType())); // Setup child object SObject cont = Schema.getGlobalDescribe().get('Contact').newSObject(); cont.put('Id', fflib_IDGenerator.generate(cont.getSObjectType())); String errorMessage = ''; try { // Call method under test SObject accWithRelationships = ((List)fflib_ApexMocksUtils.makeRelationship( 'MyInvalidParentType', 'Contact', new List { acc }, 'AccountId', new List> { new List { cont }} ))[0]; } catch (Exception exc) { errorMessage = exc.getMessage(); } System.Assert.areEqual('SObject type not found: MyInvalidParentType', errorMessage); } @isTest private static void makeRelationship_GenericOverload_ThrowsErrorOnInvalidChildType() { // Setup parent object SObject acc = Schema.getGlobalDescribe().get('Account').newSObject(); acc.put('Id', fflib_IDGenerator.generate(acc.getSObjectType())); // Setup child object SObject cont = Schema.getGlobalDescribe().get('Contact').newSObject(); cont.put('Id', fflib_IDGenerator.generate(cont.getSObjectType())); String errorMessage = ''; try { // Call method under test SObject accWithRelationships = ((List)fflib_ApexMocksUtils.makeRelationship( 'Account', 'MyInvalidChildType', new List { acc }, 'AccountId', new List> { new List { cont }} ))[0]; } catch (Exception exc) { errorMessage = exc.getMessage(); } System.Assert.areEqual('SObject type not found: MyInvalidChildType', errorMessage); } @isTest private static void makeRelationship_GenericOverload_ThrowsErrorOnInvalidFieldName() { // Setup parent object SObject acc = Schema.getGlobalDescribe().get('Account').newSObject(); acc.put('Id', fflib_IDGenerator.generate(acc.getSObjectType())); // Setup child object SObject cont = Schema.getGlobalDescribe().get('Contact').newSObject(); cont.put('Id', fflib_IDGenerator.generate(cont.getSObjectType())); String errorMessage = ''; try { // Call method under test SObject accWithRelationships = ((List)fflib_ApexMocksUtils.makeRelationship( 'Account', 'Contact', new List { acc }, 'MyInvalidField', new List> { new List { cont }} ))[0]; } catch (Exception exc) { errorMessage = exc.getMessage(); } System.Assert.areEqual('SObject field not found: MyInvalidField', errorMessage); } @IsTest private static void makeRelationship_ObjectWithNull_DoesNotThrowErrorOnJSONExceptionCanNotWriteAFieldNameExpectingAValue() { // Given Product2 prod1 = new Product2( Id = fflib_IDGenerator.generate(Product2.SObjectType), Name = 'Product1', ProductCode = 'P1', Description = null, StockKeepingUnit = 'P1' ); Product2 prod2 = new Product2( Id = fflib_IDGenerator.generate(Product2.SObjectType), Name = 'Product2', ProductCode = 'P2', Description = 'this is another product', StockKeepingUnit = 'P2' ); OpportunityLineItem oli1 = new OpportunityLineItem( Id = fflib_IDGenerator.generate(OpportunityLineItem.SObjectType), Product2Id = prod1.Id, Product2 = prod1, UnitPrice = 10, Quantity = 1 ); OpportunityLineItem oli2 = new OpportunityLineItem( Id = fflib_IDGenerator.generate(OpportunityLineItem.SObjectType), Product2Id = prod2.Id, Product2 = prod2, UnitPrice = 10, Quantity = 1 ); Opportunity opportunity = new Opportunity(); Exception exceptionThatWasCalled = null; // When Test.startTest(); try { fflib_ApexMocksUtils.makeRelationship( List.class, new List{ opportunity }, OpportunityLineItem.OpportunityId, new List>{ new List{oli1, oli2} } ); } catch (JSONException e) { exceptionThatWasCalled = e; } Test.stopTest(); // Then System.debug(exceptionThatWasCalled); Assert.isNull(exceptionThatWasCalled, 'Exception should not have been called'); } @isTest static void setReadOnlyFields_CreatedByIdSetToCurrentUserId_IdFieldSetSuccessfully() { Account acc = new Account(); Id userId = fflib_IDGenerator.generate((new User()).getSObjectType()); Test.startTest(); acc = (Account)fflib_ApexMocksUtils.setReadOnlyFields( acc, Account.class, new Map{Account.CreatedById => userId} ); Test.stopTest(); System.Assert.areEqual(userId, acc.CreatedById); } @isTest static void setReadOnlyFields_LastReferencedDateSetOnAccount_DateTimeFieldSetSuccessfully() { Account acc = new Account(); DateTime lastRefDate = DateTime.newInstanceGmt(2020, 1, 7, 23, 30, 0); Test.startTest(); acc = (Account)fflib_ApexMocksUtils.setReadOnlyFields( acc, Account.class, new Map {Account.LastReferencedDate => lastRefDate} ); Test.stopTest(); System.Assert.areEqual(lastRefDate, acc.LastReferencedDate); } @isTest static void setReadOnlyFields_IsDeletedSetOnAccount_BooleanFieldSetSuccessfully() { Account acc = new Account(); Boolean isDeleted = true; Test.startTest(); acc = (Account)fflib_ApexMocksUtils.setReadOnlyFields( acc, Account.class, new Map {Account.IsDeleted => isDeleted} ); Test.stopTest(); System.Assert.areEqual(isDeleted, acc.IsDeleted); } @isTest static void setReadOnlyFields_PolymorphicRelationJoin_FieldSetSuccessfully() { Account acc = new Account(Name='TestAccount'); Task t = new Task(); Test.startTest(); t = (Task)fflib_ApexMocksUtils.setReadOnlyFields( t, Task.class, new Map {'What' => acc} ); Test.stopTest(); System.Assert.areEqual(acc.Name, t.What.Name); } } ================================================ FILE: sfdx-source/apex-mocks/test/classes/fflib_ApexMocksUtilsTest.cls-meta.xml ================================================ 63.0 ================================================ FILE: sfdx-source/apex-mocks/test/classes/fflib_ArgumentCaptorTest.cls ================================================ /* * Copyright (c) 2016-2017 FinancialForce.com, inc. All rights reserved. */ /** * @nodoc */ @isTest private class fflib_ArgumentCaptorTest { @isTest static void thatArgumentValueIsCaptured() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); // When mockList.add('Fred'); // Then fflib_ArgumentCaptor argument = fflib_ArgumentCaptor.forClass(String.class); ((fflib_MyList.IList) mocks.verify(mockList)).add((String) argument.capture()); System.Assert.areEqual('Fred', (String)argument.getValue(), 'the argument captured is not as expected'); } @isTest static void thatCanPerformFurtherAssertionsOnCapturedArgumentValue() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); //When TestInnerClass testValue = new TestInnerClass(); testValue.i = 4; testValue.s = '5'; mockList.set(1, testValue); //Then fflib_ArgumentCaptor argument = fflib_ArgumentCaptor.forClass(TestInnerClass.class); ((fflib_MyList.IList) mocks.verify(mockList)).set(fflib_Match.anyInteger(), argument.capture()); Object capturedArg = argument.getValue(); System.Assert.areNotEqual(null, capturedArg, 'CapturedArg should not be null'); System.Assert.isInstanceOfType(capturedArg, TestInnerClass.class, 'CapturedArg should be SObject, instead was ' + capturedArg); TestInnerClass testValueCaptured = (TestInnerClass)capturedArg; System.Assert.areEqual(4, testValueCaptured.i, 'the values inside the argument captured should be the same of the original one'); System.Assert.areEqual('5', testValueCaptured.s, 'the values inside the argument captured should be the same of the original one'); } @isTest static void thatCaptureArgumentOnlyFromVerifiedMethod() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); // When mockList.add('Fred'); //the next call should be ignored because is not the method that has under verify, //even if have the same type specified in the capturer. mockList.addMore('Barney'); // Then fflib_ArgumentCaptor argument = fflib_ArgumentCaptor.forClass(String.class); ((fflib_MyList.IList) mocks.verify(mockList)).add((String) argument.capture()); System.Assert.areEqual('Fred', (String)argument.getValue(), 'the argument captured is not as expected'); System.Assert.areEqual(1, argument.getAllValues().size(), 'the argument captured should be only one'); } @isTest static void thatCaptureAllArgumentsForTheVerifiedMethods() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); List stringList = new List {'3'}; // When mockList.add('Fred'); mockList.add(stringList); mockList.clear(); // Then fflib_ArgumentCaptor argument = fflib_ArgumentCaptor.forClass(String.class); ((fflib_MyList.IList) mocks.verify(mockList)).add((String) argument.capture()); ((fflib_MyList.IList) mocks.verify(mockList)).add((List) argument.capture()); System.Assert.areEqual(stringList, (List)argument.getValue(), 'the argument captured is not as expected'); List argsCaptured = argument.getAllValues(); System.Assert.areEqual(2, argsCaptured.size(), 'expected 2 argument to be captured'); System.Assert.areEqual('Fred', (String) argsCaptured[0], 'the first value is not as expected'); } @isTest static void thatCaptureArgumentFromRequestedParameter() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); // When mockList.add('Fred', 'Barney', 'Wilma', 'Betty'); // Then fflib_ArgumentCaptor argument = fflib_ArgumentCaptor.forClass(String.class); ((fflib_MyList.IList) mocks.verify(mockList)) .add( (String) fflib_Match.eq('Fred'), (String) fflib_Match.eq('Barney'), (String) argument.capture(), (String) fflib_Match.eq('Betty')); System.Assert.areEqual('Wilma', (String)argument.getValue(), 'the argument captured is not as expected, should be Wilma because is the 3rd parameter in the call'); } @isTest static void thatCaptureLastArgument() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); // When mockList.add('Barney'); mockList.add('Fred'); // Then fflib_ArgumentCaptor argument = fflib_ArgumentCaptor.forClass(String.class); ((fflib_MyList.IList) mocks.verify(mockList, 2)).add((String) argument.capture()); System.Assert.areEqual('Fred', (String)argument.getValue(), 'the argument captured is not as expected'); } @isTest static void thatCaptureAllArguments() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); // When mockList.add('Fred'); mockList.add('Barney'); mockList.add('Wilma'); mockList.add('Betty'); // Then fflib_ArgumentCaptor argument = fflib_ArgumentCaptor.forClass(String.class); ((fflib_MyList.IList) mocks.verify(mockList, 4)).add((String) argument.capture()); List argsCaptured = argument.getAllValues(); System.Assert.areEqual(4, argsCaptured.size(), 'expected 4 argument to be captured'); System.Assert.areEqual('Fred', (String) argsCaptured[0], 'the first value is not as expected'); System.Assert.areEqual('Barney', (String) argsCaptured[1], 'the second value is not as expected'); System.Assert.areEqual('Wilma', (String) argsCaptured[2], 'the third value is not as expected'); System.Assert.areEqual('Betty', (String) argsCaptured[3], 'the forth value is not as expected'); } @isTest static void thatCaptureAllArgumentsFromMultipleMethods() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); // When mockList.add('Fred'); mockList.add('Barney'); mockList.get2(3, 'pebble'); // Then fflib_ArgumentCaptor argument = fflib_ArgumentCaptor.forClass(String.class); ((fflib_MyList.IList) mocks.verify(mockList, 2)).add((String) argument.capture()); ((fflib_MyList.IList) mocks.verify(mockList)) .get2( (Integer) fflib_Match.eq(3), (String) argument.capture()); List argsCaptured = argument.getAllValues(); System.Assert.areEqual(3, argsCaptured.size(), 'expected 3 argument to be captured'); System.Assert.areEqual('Fred', (String) argsCaptured[0], 'the first value is not as expected'); System.Assert.areEqual('Barney', (String) argsCaptured[1], 'the second value is not as expected'); System.Assert.areEqual('pebble', (String) argsCaptured[2], 'the third value is not as expected'); } @isTest static void thatCanHandleMultipleCapturesInOneMethodCall() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); // When mockList.add('Fred', 'Barney', 'Wilma', 'Betty'); // Then fflib_ArgumentCaptor argument = fflib_ArgumentCaptor.forClass(String.class); ((fflib_MyList.IList) mocks.verify(mockList)) .add( (String) fflib_Match.eq('Fred'), (String) argument.capture(), (String) argument.capture(), (String) fflib_Match.eq('Betty')); List argsCaptured = argument.getAllValues(); System.Assert.areEqual(2, argsCaptured.size(), 'expected 2 argument to be captured'); System.Assert.areEqual('Barney', (String) argsCaptured[0], 'the first value is not as expected'); System.Assert.areEqual('Wilma', (String) argsCaptured[1], 'the second value is not as expected'); } @isTest static void thatDoesNotCaptureIfNotVerified() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); // When mockList.add('3'); // Then fflib_ArgumentCaptor argument = fflib_ArgumentCaptor.forClass(List.class); ((fflib_MyList.IList) mocks.verify(mockList, fflib_ApexMocks.NEVER)) .add((List) argument.capture()); List argsCaptured = argument.getAllValues(); System.Assert.areEqual(0, argsCaptured.size(), 'expected 0 argument to be captured'); System.Assert.areEqual(null, argument.getValue(), 'no value should be captured, so must return null'); } @isTest static void thatCaptureOnlyMethodsThatMatchesWithOtherMatcherAsWell() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); // When mockList.add('Same', 'Same', 'First call', 'First call'); mockList.add('Same', 'Same', 'Second call', 'Second call'); // Then fflib_ArgumentCaptor argument = fflib_ArgumentCaptor.forClass(String.class); ((fflib_MyList.IList) mocks.verify(mockList)).add( fflib_Match.eqString('Same'), fflib_Match.eqString('Same'), (String)argument.capture(), fflib_Match.eqString('First call')); System.Assert.areEqual('First call', (String)argument.getValue()); } @isTest static void thatDoesNotCaptureAnythingWhenCaptorIsWrappedInAMatcher() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); // When mockList.add('Same', 'Same', 'First call', 'First call'); mockList.add('Same', 'Same', 'Second call', 'Second call'); // Then fflib_ArgumentCaptor argument = fflib_ArgumentCaptor.forClass(String.class); ((fflib_MyList.IList) mocks.verify(mockList)).add( (String) fflib_Match.allOf( fflib_Match.eqString('Same'), fflib_Match.eqString('Same'), argument.capture()), (String) fflib_Match.allOf( fflib_Match.eqString('Same'), fflib_Match.eqString('Same'), argument.capture()), (String) fflib_Match.allOf( argument.capture(), fflib_Match.eqString('First call')), (String) fflib_Match.allOf( argument.capture(), fflib_Match.eqString('First call')) ); List capturedValues = argument.getAllValues(); System.Assert.areEqual(0, capturedValues.size(), 'nothing should have been capture because the matcher it not really a capture type, but a allOf()'); System.Assert.isNull((String)argument.getValue(), 'nothing should have been capture because the matcher it not really a capture type, but a allOf()'); } @isTest static void thatArgumentValueIsCapturedWithInOrderVerification() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); fflib_InOrder inOrder1 = new fflib_InOrder(mocks, new List{ mockList }); // When mockList.add('Fred'); // Then fflib_ArgumentCaptor argument = fflib_ArgumentCaptor.forClass(String.class); ((fflib_MyList.IList)inOrder1.verify(mockList, mocks.calls(1))).add((String) argument.capture()); System.Assert.areEqual('Fred', (String)argument.getValue(), 'the argument captured is not as expected'); } @isTest static void thatCanPerformFurtherAssertionsOnCapturedArgumentValueWithInOrderVerification() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); fflib_InOrder inOrder1 = new fflib_InOrder(mocks, new List{ mockList }); //When TestInnerClass testValue = new TestInnerClass(); testValue.i = 4; testValue.s = '5'; mockList.set(1, testValue); //Then fflib_ArgumentCaptor argument = fflib_ArgumentCaptor.forClass(TestInnerClass.class); ((fflib_MyList.IList) inOrder1.verify(mockList, mocks.calls(1))).set(fflib_Match.anyInteger(), argument.capture()); Object capturedArg = argument.getValue(); System.Assert.areNotEqual(null, capturedArg, 'CapturedArg should not be null'); System.Assert.isInstanceOfType(capturedArg, TestInnerClass.class, 'CapturedArg should be SObject, instead was ' + capturedArg); TestInnerClass testValueCaptured = (TestInnerClass)capturedArg; System.Assert.areEqual(4, testValueCaptured.i, 'the values inside the argument captured should be the same of the original one'); System.Assert.areEqual('5', testValueCaptured.s, 'the values inside the argument captured should be the same of the original one'); } @isTest static void thatCaptureArgumentOnlyFromVerifiedMethodWithInOrderVerification() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); fflib_InOrder inOrder1 = new fflib_InOrder(mocks, new List{ mockList }); // When mockList.add('Fred'); //the next call should be ignored because is not the method that has under verify, //even if have the same type specified in the capturer. mockList.addMore('Barney'); // Then fflib_ArgumentCaptor argument = fflib_ArgumentCaptor.forClass(String.class); ((fflib_MyList.IList) inOrder1.verify(mockList, mocks.calls(1))).add((String) argument.capture()); System.Assert.areEqual('Fred', (String)argument.getValue(), 'the argument captured is not as expected'); System.Assert.areEqual(1, argument.getAllValues().size(), 'the argument captured should be only one'); } @isTest static void thatCaptureAllArgumentsForTheVerifiedMethodsWithInOrderVerification() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); fflib_InOrder inOrder1 = new fflib_InOrder(mocks, new List{ mockList }); List stringList = new List {'3'}; // When mockList.add('Fred'); mockList.add(stringList); mockList.clear(); // Then fflib_ArgumentCaptor argument = fflib_ArgumentCaptor.forClass(String.class); ((fflib_MyList.IList) inOrder1.verify(mockList, mocks.calls(1))).add((String) argument.capture()); ((fflib_MyList.IList) inOrder1.verify(mockList, mocks.calls(1))).add((List) argument.capture()); System.Assert.areEqual(stringList, (List)argument.getValue(), 'the argument captured is not as expected'); List argsCaptured = argument.getAllValues(); System.Assert.areEqual(2, argsCaptured.size(), 'expected 2 argument to be captured'); System.Assert.areEqual('Fred', (String) argsCaptured[0], 'the first value is not as expected'); } @isTest static void thatCaptureArgumentFromRequestedParameterWithInOrderVerification() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); fflib_InOrder inOrder1 = new fflib_InOrder(mocks, new List{ mockList }); // When mockList.add('Fred', 'Barney', 'Wilma', 'Betty'); // Then fflib_ArgumentCaptor argument = fflib_ArgumentCaptor.forClass(String.class); ((fflib_MyList.IList) inOrder1.verify(mockList, mocks.calls(1))) .add( (String) fflib_Match.eq('Fred'), (String) fflib_Match.eq('Barney'), (String) argument.capture(), (String) fflib_Match.eq('Betty')); System.Assert.areEqual('Wilma', (String)argument.getValue(), 'the argument captured is not as expected, should be Wilma because is the 3rd parameter in the call'); } @isTest static void thatCaptureLastArgumentWithInOrderVerification() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); fflib_InOrder inOrder1 = new fflib_InOrder(mocks, new List{ mockList }); // When mockList.add('Barney'); mockList.add('Fred'); // Then fflib_ArgumentCaptor argument = fflib_ArgumentCaptor.forClass(String.class); ((fflib_MyList.IList) inOrder1.verify(mockList, mocks.calls(2))).add((String) argument.capture()); System.Assert.areEqual('Fred', (String)argument.getValue(), 'the argument captured is not as expected'); } @isTest static void thatCaptureAllArgumentsWithInOrderVerification() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); fflib_InOrder inOrder1 = new fflib_InOrder(mocks, new List{ mockList }); // When mockList.add('Fred'); mockList.add('Barney'); mockList.add('Wilma'); mockList.add('Betty'); // Then fflib_ArgumentCaptor argument = fflib_ArgumentCaptor.forClass(String.class); ((fflib_MyList.IList) inOrder1.verify(mockList, mocks.calls(4))).add((String) argument.capture()); List argsCaptured = argument.getAllValues(); System.Assert.areEqual(4, argsCaptured.size(), 'expected 4 argument to be captured'); System.Assert.areEqual('Fred', (String) argsCaptured[0], 'the first value is not as expected'); System.Assert.areEqual('Barney', (String) argsCaptured[1], 'the second value is not as expected'); System.Assert.areEqual('Wilma', (String) argsCaptured[2], 'the third value is not as expected'); System.Assert.areEqual('Betty', (String) argsCaptured[3], 'the forth value is not as expected'); } @isTest static void thatCaptureAllArgumentsFromMultipleMethodsWithInOrderVerification() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); fflib_InOrder inOrder1 = new fflib_InOrder(mocks, new List{ mockList }); // When mockList.add('Fred'); mockList.add('Barney'); mockList.get2(3, 'pebble'); // Then fflib_ArgumentCaptor argument = fflib_ArgumentCaptor.forClass(String.class); ((fflib_MyList.IList) inOrder1.verify(mockList, mocks.calls(2))).add((String) argument.capture()); ((fflib_MyList.IList) inOrder1.verify(mockList, mocks.calls(1))) .get2( (Integer) fflib_Match.eq(3), (String) argument.capture()); List argsCaptured = argument.getAllValues(); System.Assert.areEqual(3, argsCaptured.size(), 'expected 3 argument to be captured'); System.Assert.areEqual('Fred', (String) argsCaptured[0], 'the first value is not as expected'); System.Assert.areEqual('Barney', (String) argsCaptured[1], 'the second value is not as expected'); System.Assert.areEqual('pebble', (String) argsCaptured[2], 'the third value is not as expected'); } @isTest static void thatCanHandleMultipleCapturesInOneMethodCallWithInOrderVerification() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); fflib_InOrder inOrder1 = new fflib_InOrder(mocks, new List{ mockList }); // When mockList.add('Fred', 'Barney', 'Wilma', 'Betty'); // Then fflib_ArgumentCaptor argument = fflib_ArgumentCaptor.forClass(String.class); ((fflib_MyList.IList) inOrder1.verify(mockList, mocks.calls(1))) .add( (String) fflib_Match.eq('Fred'), (String) argument.capture(), (String) argument.capture(), (String) fflib_Match.eq('Betty')); List argsCaptured = argument.getAllValues(); System.Assert.areEqual(2, argsCaptured.size(), 'expected 2 argument to be captured'); System.Assert.areEqual('Barney', (String) argsCaptured[0], 'the first value is not as expected'); System.Assert.areEqual('Wilma', (String) argsCaptured[1], 'the second value is not as expected'); } @isTest static void thatDoesNotCaptureIfNotVerifiedWithInOrderVerification() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); fflib_InOrder inOrder1 = new fflib_InOrder(mocks, new List{ mockList }); // When mockList.add('3'); // Then fflib_ArgumentCaptor argument = fflib_ArgumentCaptor.forClass(List.class); ((fflib_MyList.IList) inOrder1.verify(mockList, mocks.never())) .add((List) argument.capture()); List argsCaptured = argument.getAllValues(); System.Assert.areEqual(0, argsCaptured.size(), 'expected 0 argument to be captured'); System.Assert.areEqual(null, argument.getValue(), 'no value should be captured, so must return null'); } @isTest static void thatCaptureOnlyMethodsThatMatchesWithOtherMatcherAsWellWithInOrderVerification() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); fflib_InOrder inOrder1 = new fflib_InOrder(mocks, new List{ mockList }); // When mockList.add('Same', 'Same', 'First call', 'First call'); mockList.add('Same', 'Same', 'Second call', 'Second call'); // Then fflib_ArgumentCaptor argument = fflib_ArgumentCaptor.forClass(String.class); ((fflib_MyList.IList) inOrder1.verify(mockList, mocks.calls(1))).add( fflib_Match.eqString('Same'), fflib_Match.eqString('Same'), (String)argument.capture(), fflib_Match.eqString('First call')); System.Assert.areEqual('First call', (String)argument.getValue()); } @isTest static void thatDoesNotCaptureAnythingWhenCaptorIsWrappedInAMatcherWithInOrderVerification() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); fflib_InOrder inOrder1 = new fflib_InOrder(mocks, new List{ mockList }); // When mockList.add('Same', 'Same', 'First call', 'First call'); mockList.add('Same', 'Same', 'Second call', 'Second call'); // Then fflib_ArgumentCaptor argument = fflib_ArgumentCaptor.forClass(String.class); ((fflib_MyList.IList) inOrder1.verify(mockList, mocks.calls(1))).add( (String) fflib_Match.allOf( fflib_Match.eqString('Same'), fflib_Match.eqString('Same'), argument.capture()), (String) fflib_Match.allOf( fflib_Match.eqString('Same'), fflib_Match.eqString('Same'), argument.capture()), (String) fflib_Match.allOf( argument.capture(), fflib_Match.eqString('First call')), (String) fflib_Match.allOf( argument.capture(), fflib_Match.eqString('First call')) ); List capturedValues = argument.getAllValues(); System.Assert.areEqual(0, capturedValues.size(), 'nothing should have been capture because the matcher it not really a capture type, but a allOf()'); System.Assert.isNull((String)argument.getValue(), 'nothing should have been capture because the matcher it not really a capture type, but a allOf()'); } @isTest static void thatCaptureAllArgumentswhenMethodIsCalledWithTheSameArgument() { // Given fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_MyList mockList = (fflib_MyList)mocks.mock(fflib_MyList.class); // When mockList.add('Fred'); mockList.add('Barney'); mockList.add('Wilma'); mockList.add('Barney'); mockList.add('Barney'); mockList.add('Betty'); // Then fflib_ArgumentCaptor argument = fflib_ArgumentCaptor.forClass(String.class); ((fflib_MyList.IList) mocks.verify(mockList, 6)).add((String) argument.capture()); List argsCaptured = argument.getAllValues(); System.Assert.areEqual(6, argsCaptured.size(), 'expected 6 arguments to be captured'); System.Assert.areEqual('Fred', (String) argsCaptured[0], 'the first value is not as expected'); System.Assert.areEqual('Barney', (String) argsCaptured[1], 'the second value is not as expected'); System.Assert.areEqual('Wilma', (String) argsCaptured[2], 'the third value is not as expected'); System.Assert.areEqual('Barney', (String) argsCaptured[3], 'the fourth value is not as expected'); System.Assert.areEqual('Barney', (String) argsCaptured[4], 'the fifth value is not as expected'); System.Assert.areEqual('Betty', (String) argsCaptured[5], 'the sixth value is not as expected'); } private class TestInnerClass { public Integer i; public String s; } } ================================================ FILE: sfdx-source/apex-mocks/test/classes/fflib_ArgumentCaptorTest.cls-meta.xml ================================================ 63.0 Active ================================================ FILE: sfdx-source/apex-mocks/test/classes/fflib_IDGeneratorTest.cls ================================================ /** * Copyright (c) 2014, FinancialForce.com, inc * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * - Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * - Neither the name of the FinancialForce.com, inc nor the names of its contributors * may be used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ @isTest private class fflib_IDGeneratorTest { @isTest static void itShouldGenerateValidIDs() { String id1 = fflib_IDGenerator.generate(Account.SObjectType); String id2 = fflib_IDGenerator.generate(Account.SObjectType); String id3 = fflib_IDGenerator.generate(Account.SObjectType); String id4 = fflib_IDGenerator.generate(Account.SObjectType); String id5 = fflib_IDGenerator.generate(Account.SObjectType); String id6 = fflib_IDGenerator.generate(Account.SObjectType); String id7 = fflib_IDGenerator.generate(Account.SObjectType); String id8 = fflib_IDGenerator.generate(Account.SObjectType); String id9 = fflib_IDGenerator.generate(Account.SObjectType); String id10 = fflib_IDGenerator.generate(Account.SObjectType); String id11 = fflib_IDGenerator.generate(Account.SObjectType); System.Assert.areEqual('001000000000001AAA', id1); System.Assert.areEqual('001000000000002AAA', id2); System.Assert.areEqual('001000000000003AAA', id3); System.Assert.areEqual('001000000000004AAA', id4); System.Assert.areEqual('001000000000005AAA', id5); System.Assert.areEqual('001000000000006AAA', id6); System.Assert.areEqual('001000000000007AAA', id7); System.Assert.areEqual('001000000000008AAA', id8); System.Assert.areEqual('001000000000009AAA', id9); System.Assert.areEqual('001000000000010AAA', id10); System.Assert.areEqual('001000000000011AAA', id11); } } ================================================ FILE: sfdx-source/apex-mocks/test/classes/fflib_IDGeneratorTest.cls-meta.xml ================================================ 63.0 ================================================ FILE: sfdx-source/apex-mocks/test/classes/fflib_InOrderTest.cls ================================================ /* Copyright (c) 2014-2017 FinancialForce.com, inc. All rights reserved. */ @isTest private class fflib_InOrderTest { private static fflib_ApexMocks MY_MOCKS = new fflib_ApexMocks(); @isTest static void thatVerifyInOrderAllTheMethodsCalled() { // Given fflib_MyList firstMock = (fflib_MyList)MY_MOCKS.mock(fflib_MyList.class); fflib_InOrder inOrder1 = new fflib_InOrder(MY_MOCKS, new List{ firstMock }); // When firstMock.add('1-1'); firstMock.add('1-2'); firstMock.add('1-3'); firstMock.add('1-4'); // Then ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(1))).add('1-1'); ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(1))).add('1-2'); ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(1))).add('1-3'); ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(1))).add('1-4'); try { ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(1))).add('1-2'); System.Assert.fail('It should fail because 1-2 is in the wrong order'); } catch (fflib_ApexMocks.ApexMocksException error) { System.Assert.areEqual('EXPECTED COUNT: 1 in order' +'\nACTUAL COUNT: 0' +'\nMETHOD: fflib_MyList__sfdc_ApexStub.add(String)' +'\n---' +'\nACTUAL ARGS: ("1-1"), ("1-2"), ("1-3"), ("1-4")' +'\n---' +'\nEXPECTED ARGS: "1-2"', error.getMessage(), 'Unexpected verify fail message'); } } @isTest static void thatVerifyInOrderDifferentMethodsCalledWithSameArguments() { // Given fflib_MyList firstMock = (fflib_MyList)MY_MOCKS.mock(fflib_MyList.class); fflib_InOrder inOrder1 = new fflib_InOrder(MY_MOCKS, new List{ firstMock }); // When firstMock.add('1-1'); firstMock.addMore('1-1'); firstMock.add('1-2'); firstMock.addMore('1-2'); firstMock.add('1-3'); firstMock.addMore('1-3'); firstMock.add('1-4'); firstMock.addMore('1-4'); // Then ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(1))).add('1-1'); ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(1))).addMore('1-1'); ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(1))).addMore('1-3'); ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(1))).add('1-4'); } @isTest static void thatVerifyInOrderDifferentMethodsCalledWithSameArgumentsOrderFail() { // Given fflib_MyList firstMock = (fflib_MyList)MY_MOCKS.mock(fflib_MyList.class); fflib_InOrder inOrder1 = new fflib_InOrder(MY_MOCKS, new List{ firstMock }); // When firstMock.add('1-1'); firstMock.addMore('1-1'); firstMock.add('1-2'); firstMock.addMore('1-2'); // Then ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(1))).addMore('1-1'); try { ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(1))).add('1-1'); System.Assert.fail('It should fail because 1-1 is called before the addMore(1-1)'); } catch (fflib_ApexMocks.ApexMocksException error) { System.Assert.areEqual('EXPECTED COUNT: 1 in order' +'\nACTUAL COUNT: 0' +'\nMETHOD: fflib_MyList__sfdc_ApexStub.add(String)' +'\n---' +'\nACTUAL ARGS: ("1-1"), ("1-1"), ("1-2"), ("1-2")' +'\n---' +'\nEXPECTED ARGS: "1-1"', error.getMessage(), 'Unexpected verify fail message'); } } @isTest static void thatVerifyInOrderDifferentMethodsCalledWithSameArgumentsDoubleCallFail() { // Given fflib_MyList firstMock = (fflib_MyList)MY_MOCKS.mock(fflib_MyList.class); fflib_InOrder inOrder1 = new fflib_InOrder(MY_MOCKS, new List{ firstMock }); // When firstMock.add('1-1'); firstMock.addMore('1-1'); firstMock.add('1-2'); firstMock.addMore('1-2'); // Then ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(1))).addMore('1-1'); try { ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(1))).addMore('1-1'); System.Assert.fail('It should fail because addMore(1-1) is called only Once'); } catch (fflib_ApexMocks.ApexMocksException error) { System.Assert.areEqual('EXPECTED COUNT: 1 in order' + '\nACTUAL COUNT: 0' + '\nMETHOD: fflib_MyList__sfdc_ApexStub.addMore(String)' + '\n---' + '\nACTUAL ARGS: ("1-1"), ("1-1"), ("1-2"), ("1-2")' + '\n---' + '\nEXPECTED ARGS: "1-1"', error.getMessage(), 'Unexpected verify fail message'); } } @isTest static void thatVerifyInOrderCallMethodWithMatches() { // Given fflib_MyList firstMock = (fflib_MyList)MY_MOCKS.mock(fflib_MyList.class); fflib_InOrder inOrder1 = new fflib_InOrder(MY_MOCKS, new List{ firstMock }); // When firstMock.add('1-0'); firstMock.add('1-11'); firstMock.add('1-12'); firstMock.add('1-3'); firstMock.add('1-4'); // Then ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(2))).add(fflib_Match.stringStartsWith('1-1')); ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(1))).add('1-4'); } @isTest static void thatVerifyInOrderCallMethodWithMatchesFailsIfVerifyACallAlreadyInTheMatcher() { // Given fflib_MyList firstMock = (fflib_MyList)MY_MOCKS.mock(fflib_MyList.class); fflib_InOrder inOrder1 = new fflib_InOrder(MY_MOCKS, new List{ firstMock }); // When firstMock.add('1-0'); firstMock.add('1-11'); firstMock.add('1-12'); firstMock.add('1-3'); firstMock.add('1-4'); // Then ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(2))).add(fflib_Match.stringStartsWith('1-1')); ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(1))).add('1-4'); try { ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(1))).add('1-11'); System.Assert.fail('It should fail because addMore(1-11) has been already verified using the matchers'); } catch (fflib_ApexMocks.ApexMocksException error) { System.Assert.areEqual('EXPECTED COUNT: 1 in order' +'\nACTUAL COUNT: 0' +'\nMETHOD: fflib_MyList__sfdc_ApexStub.add(String)' +'\n---' +'\nACTUAL ARGS: ("1-0"), ("1-11"), ("1-12"), ("1-3"), ("1-4")' +'\n---' +'\nEXPECTED ARGS: "1-11"', error.getMessage(), 'Unexpected verify fail message'); } } @isTest static void thatVerifyInOrderCallMethodWithMultipleMatches() { // Given fflib_MyList firstMock = (fflib_MyList)MY_MOCKS.mock(fflib_MyList.class); fflib_InOrder inOrder1 = new fflib_InOrder(MY_MOCKS, new List{ firstMock }); // When firstMock.add('1-0'); firstMock.add('1-1'); firstMock.add('1-3'); firstMock.add('1-4'); firstMock.add('2-0'); firstMock.add('2-1'); firstMock.add('2-3'); firstMock.add('2-4'); // Then ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(4))).add(fflib_Match.stringStartsWith('1-')); ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(4))).add(fflib_Match.stringStartsWith('2-')); } @isTest static void thatVerifyInOrderCallMethodWithMultipleMatchesMixed() { // Given fflib_MyList firstMock = (fflib_MyList)MY_MOCKS.mock(fflib_MyList.class); fflib_InOrder inOrder1 = new fflib_InOrder(MY_MOCKS, new List{ firstMock }); // When firstMock.add('1-1'); firstMock.add('2-1'); firstMock.add('1-2'); firstMock.add('2-2'); firstMock.add('1-3'); firstMock.add('2-3'); firstMock.add('1-4'); firstMock.add('2-4'); // Then ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(4))).add(fflib_Match.stringStartsWith('1-')); ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(1))).add(fflib_Match.stringStartsWith('2-')); } @isTest static void thatVerifyInOrderCallMethodWithMultipleMatchesMixedFailWhenMatcherHaveAlreadyVerifiedMethod() { // Given fflib_MyList firstMock = (fflib_MyList)MY_MOCKS.mock(fflib_MyList.class); fflib_InOrder inOrder1 = new fflib_InOrder(MY_MOCKS, new List{ firstMock }); // When firstMock.add('1-1'); firstMock.add('2-1'); firstMock.add('1-2'); firstMock.add('2-2'); firstMock.add('1-3'); firstMock.add('2-3'); firstMock.add('1-4'); firstMock.add('2-4'); // Then ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(4))).add(fflib_Match.stringStartsWith('1-')); try { ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(4))).add('1-11'); System.Assert.fail('It should fail because only one call for the 2- is available to verify'); } catch (fflib_ApexMocks.ApexMocksException error) { System.Assert.areEqual('EXPECTED COUNT: 4 in order' +'\nACTUAL COUNT: 0' +'\nMETHOD: fflib_MyList__sfdc_ApexStub.add(String)' +'\n---' +'\nACTUAL ARGS: ("1-1"), ("2-1"), ("1-2"), ("2-2"), ("1-3"), ("2-3"), ("1-4"), ("2-4")' +'\n---' +'\nEXPECTED ARGS: "1-11"', error.getMessage(), 'Unexpected verify fail message'); } } @isTest static void thatVerifyInOrderCanSkipMethodsCalledUntilFindTheOneThatNeedsVerify() { // Given fflib_MyList firstMock = (fflib_MyList)MY_MOCKS.mock(fflib_MyList.class); fflib_InOrder inOrder1 = new fflib_InOrder(MY_MOCKS, new List{ firstMock }); // When firstMock.add('1-1'); firstMock.add('1-2'); firstMock.add('1-3'); firstMock.add('1-4'); // Then ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(1))).add('1-1'); ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(1))).add('1-4'); try { ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(1))).add('1-2'); System.Assert.fail('It should fail because is out of order'); } catch (fflib_ApexMocks.ApexMocksException error) { System.Assert.areEqual('EXPECTED COUNT: 1 in order' +'\nACTUAL COUNT: 0' +'\nMETHOD: fflib_MyList__sfdc_ApexStub.add(String)' +'\n---' +'\nACTUAL ARGS: ("1-1"), ("1-2"), ("1-3"), ("1-4")' +'\n---' +'\nEXPECTED ARGS: "1-2"', error.getMessage(), 'Unexpected verify fail message'); } } @isTest static void thatVerifyInOrderCanHandleMultipleMethodsCalls() { // Given fflib_MyList firstMock = (fflib_MyList)MY_MOCKS.mock(fflib_MyList.class); fflib_InOrder inOrder1 = new fflib_InOrder(MY_MOCKS, new List{ firstMock }); // When firstMock.add('1-1'); firstMock.add('1-2'); firstMock.add('1-2'); firstMock.add('1-2'); firstMock.add('1-3'); firstMock.add('1-4'); // Then ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(3))).add('1-2'); ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(1))).add('1-4'); } @isTest static void thatVerifyInOrderCanHandleMultipleMethodsCallsAndNotFailsIfVerifyCountIsGreaterThenExpected() { // Given fflib_MyList firstMock = (fflib_MyList)MY_MOCKS.mock(fflib_MyList.class); fflib_InOrder inOrder1 = new fflib_InOrder(MY_MOCKS, new List{ firstMock }); // When firstMock.add('1-1'); firstMock.add('1-2'); firstMock.add('1-2'); firstMock.add('1-2'); firstMock.add('1-3'); firstMock.add('1-4'); // Then ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(2))).add('1-2'); } @isTest static void thatVerifyInOrderCanHandleMultipleMethodsCallsButFailsIfVerifyCountIsLessThenExpected() { // Given fflib_MyList firstMock = (fflib_MyList)MY_MOCKS.mock(fflib_MyList.class); fflib_InOrder inOrder1 = new fflib_InOrder(MY_MOCKS, new List{ firstMock }); // When firstMock.add('1-1'); firstMock.add('1-2'); firstMock.add('1-2'); firstMock.add('1-2'); firstMock.add('1-3'); firstMock.add('1-4'); // Then try { ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(4))).add('1-2'); System.Assert.fail('It should fail because is actually called only 3 times'); } catch (fflib_ApexMocks.ApexMocksException e) { System.Assert.areEqual('EXPECTED COUNT: 4 in order' +'\nACTUAL COUNT: 3' +'\nMETHOD: fflib_MyList__sfdc_ApexStub.add(String)' +'\n---' +'\nACTUAL ARGS: ("1-1"), ("1-2"), ("1-2"), ("1-2"), ("1-3"), ("1-4")' +'\n---' +'\nEXPECTED ARGS: "1-2"', e.getMessage(), 'Unexpected verify fail message'); } } @isTest static void thatVerifyInOrderCanHandleMultipleMocks() { // Given fflib_MyList firstMock = (fflib_MyList)MY_MOCKS.mock(fflib_MyList.class); fflib_MyList secondMock = (fflib_MyList)MY_MOCKS.mock(fflib_MyList.class); fflib_MyList thirdMock = (fflib_MyList)MY_MOCKS.mock(fflib_MyList.class); fflib_InOrder inOrder = new fflib_InOrder(MY_MOCKS, new List{ firstMock, secondMock }); // When firstMock.add('1-1'); secondMock.add('2-1'); thirdMock.add('3-1'); firstMock.add('1-2'); secondMock.add('2-2'); thirdMock.add('3-2'); firstMock.add('1-1'); firstMock.add('1-3'); secondMock.add('2-3'); thirdMock.add('3-3'); // Then ((fflib_MyList.IList)inOrder.verify(firstMock, MY_MOCKS.calls(1))).add('1-1'); ((fflib_MyList.IList)inOrder.verify(secondMock, MY_MOCKS.calls(1))).add('2-1'); ((fflib_MyList.IList)inOrder.verify(firstMock, MY_MOCKS.calls(1))).add('1-2'); ((fflib_MyList.IList)inOrder.verify(secondMock, MY_MOCKS.calls(1))).add('2-2'); ((fflib_MyList.IList)inOrder.verify(firstMock, MY_MOCKS.calls(1))).add('1-3'); ((fflib_MyList.IList)inOrder.verify(secondMock, MY_MOCKS.calls(1))).add('2-3'); ((fflib_MyList.IList)MY_MOCKS.verify(thirdMock, MY_MOCKS.times(3))).add(fflib_Match.stringStartsWith('3-')); } @isTest static void thatVerifyInOrderCanHandleMixedInOrderInstance() { // Given fflib_MyList firstMock = (fflib_MyList)MY_MOCKS.mock(fflib_MyList.class); fflib_MyList secondMock = (fflib_MyList)MY_MOCKS.mock(fflib_MyList.class); fflib_MyList thirdMock = (fflib_MyList)MY_MOCKS.mock(fflib_MyList.class); fflib_InOrder inOrder1 = new fflib_InOrder(MY_MOCKS, new List{ firstMock }); fflib_InOrder inOrder2 = new fflib_InOrder(MY_MOCKS, new List{ firstMock, secondMock }); // When firstMock.add('1-1'); secondMock.add('2-1'); thirdMock.add('3-1'); firstMock.add('1-2'); secondMock.add('2-2'); thirdMock.add('3-2'); firstMock.add('1-1'); firstMock.add('1-3'); secondMock.add('2-3'); thirdMock.add('3-3'); // Then ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(2))).add('1-1'); ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(1))).add('1-3'); ((fflib_MyList.IList)inOrder2.verify(firstMock, MY_MOCKS.calls(1))).add('1-1'); ((fflib_MyList.IList)inOrder2.verify(firstMock, MY_MOCKS.calls(1))).add('1-2'); ((fflib_MyList.IList)inOrder2.verify(secondMock, MY_MOCKS.calls(1))).add('2-2'); ((fflib_MyList.IList)inOrder2.verify(firstMock, MY_MOCKS.calls(1))).add('1-3'); ((fflib_MyList.IList)inOrder2.verify(secondMock, MY_MOCKS.calls(1))).add('2-3'); ((fflib_MyList.IList)MY_MOCKS.verify(thirdMock, MY_MOCKS.times(3))).add(fflib_Match.stringStartsWith('3-')); } @isTest static void thatVerifyInOrderThrownExceptionIfVerifyMockInstanceNotInTheSet() { // Given fflib_MyList firstMock = (fflib_MyList)MY_MOCKS.mock(fflib_MyList.class); fflib_MyList secondMock = (fflib_MyList)MY_MOCKS.mock(fflib_MyList.class); fflib_InOrder inOrder1 = new fflib_InOrder(MY_MOCKS, new List{ firstMock }); // When firstMock.add('1-1'); secondMock.add('2-1'); // Then try { ((fflib_MyList.IList)inOrder1.verify(secondMock, MY_MOCKS.calls(1))).add('2-1'); System.Assert.fail('An exception was expected, because this verify is not in the list of the mocks to verify'); } catch(fflib_ApexMocks.ApexMocksException mockexcep) { System.Assert.areEqual('EXPECTED COUNT: 1 in order' + '\nACTUAL COUNT: 0' + '\nMETHOD: fflib_MyList__sfdc_ApexStub.add(String)' + '\n---' + '\nACTUAL ARGS: ("1-1"), ("2-1")' + '\n---' + '\nEXPECTED ARGS: "2-1"', mockexcep.getMessage(), 'Unexpected verify fail message'); } } @isTest static void thatVerifyInOrderThrownExceptionWithCustomMessage() { // Given fflib_MyList firstMock = (fflib_MyList)MY_MOCKS.mock(fflib_MyList.class); fflib_InOrder inOrder1 = new fflib_InOrder(MY_MOCKS, new List{ firstMock }); String customErrorMesage = 'Some custom error message'; // When firstMock.add('1-1'); firstMock.add('1-2'); ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(1))).add('1-2'); // Then try { ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.description(customErrorMesage))).add('1-1'); System.Assert.fail('expected some exception '); } catch (fflib_ApexMocks.ApexMocksException e) { System.Assert.areEqual('EXPECTED COUNT: 1 in order' + '\nACTUAL COUNT: 0' + '\nMETHOD: fflib_MyList__sfdc_ApexStub.add(String)' + '\nSome custom error message' + '\n---' + '\nACTUAL ARGS: ("1-1"), ("1-2")' + '\n---' + '\nEXPECTED ARGS: "1-1"', e.getMessage(), 'Unexpected verify fail message'); } } @isTest static void thatVerifyAtMostThrowsExceptionBecauseNotImplemented() { // Given fflib_MyList firstMock = (fflib_MyList)MY_MOCKS.mock(fflib_MyList.class); fflib_InOrder inOrder1 = new fflib_InOrder(MY_MOCKS, new List{ firstMock }); // When firstMock.add('1-1'); firstMock.add('2-1'); firstMock.add('1-1'); firstMock.add('1-1'); firstMock.add('1-1'); firstMock.add('2-1'); // Then ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(1))).add('1-1'); ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(1))).add('2-1'); try { ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.atMost(3))).add('1-1'); System.Assert.fail('an exception was expected because the method is not implemented for the InOrder class'); } catch (fflib_ApexMocks.ApexMocksException mockExcept) { String expectedMessage = 'The atMost method is not implemented for the fflib_InOrder class'; System.Assert.areEqual(expectedMessage, mockExcept.getMessage(), ' the error message is not as expected'); } } @isTest static void thatVerifyBetweenThrowsExceptionBecauseNotImplemented() { // Given fflib_MyList firstMock = (fflib_MyList)MY_MOCKS.mock(fflib_MyList.class); fflib_InOrder inOrder1 = new fflib_InOrder(MY_MOCKS, new List{ firstMock }); // When firstMock.add('1-1'); firstMock.add('2-1'); firstMock.add('1-1'); firstMock.add('1-1'); firstMock.add('1-1'); firstMock.add('1-1'); firstMock.add('2-1'); // Then ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(1))).add('1-1'); ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(1))).add('2-1'); try { ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.between(3, 5))).add('1-1'); System.Assert.fail('an exception was expected because the method is not implemented for the InOrder class'); } catch (fflib_ApexMocks.ApexMocksException mockExcept) { String expectedMessage = 'The between method is not implemented for the fflib_InOrder class'; System.Assert.areEqual(expectedMessage, mockExcept.getMessage(), ' the error message is not as expected'); } } @isTest static void thatVerifyNever() { // Given fflib_MyList firstMock = (fflib_MyList)MY_MOCKS.mock(fflib_MyList.class); fflib_InOrder inOrder1 = new fflib_InOrder(MY_MOCKS, new List{ firstMock }); // When firstMock.add('1-1'); firstMock.add('2-1'); firstMock.add('1-1'); firstMock.add('1-1'); firstMock.add('1-1'); firstMock.add('1-1'); firstMock.add('2-1'); // Then ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(1))).add('1-1'); ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(1))).add('2-1'); ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.never())).add('3-1'); } @isTest static void thatVerifyNeverWithMatchers() { // Given fflib_MyList firstMock = (fflib_MyList)MY_MOCKS.mock(fflib_MyList.class); fflib_InOrder inOrder1 = new fflib_InOrder(MY_MOCKS, new List{ firstMock }); // When firstMock.add('1-1'); firstMock.add('2-1'); firstMock.add('1-1'); firstMock.add('1-1'); firstMock.add('1-1'); firstMock.add('1-1'); firstMock.add('2-1'); // Then ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(1))).add('1-1'); ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(1))).add('2-1'); ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.never())).add(fflib_Match.stringStartsWith('3-')); } @isTest static void thatVerifyNeverFailsWhenCalled() { // Given fflib_MyList firstMock = (fflib_MyList)MY_MOCKS.mock(fflib_MyList.class); fflib_InOrder inOrder1 = new fflib_InOrder(MY_MOCKS, new List{ firstMock }); // When firstMock.add('1-1'); firstMock.add('2-1'); firstMock.add('1-1'); firstMock.add('1-1'); firstMock.add('1-1'); firstMock.add('1-1'); firstMock.add('2-1'); // Then ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(1))).add('1-1'); ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(1))).add('2-1'); try { ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.never())).add('1-1'); System.Assert.fail('expected some exception because the method has been called'); } catch (fflib_ApexMocks.ApexMocksException e) { System.Assert.areEqual('EXPECTED COUNT: 0 in order' + '\nACTUAL COUNT: 4' + '\nMETHOD: fflib_MyList__sfdc_ApexStub.add(String)' + '\n---' + '\nACTUAL ARGS: ("1-1"), ("2-1"), ("1-1"), ("1-1"), ("1-1"), ("1-1"), ("2-1")' + '\n---' + '\nEXPECTED ARGS: "1-1"', e.getMessage(), 'Unexpected verify fail message'); } } @isTest static void thatVerifyNeverFailsWhenCalledWithMatchers() { // Given fflib_MyList firstMock = (fflib_MyList)MY_MOCKS.mock(fflib_MyList.class); fflib_InOrder inOrder1 = new fflib_InOrder(MY_MOCKS, new List{ firstMock }); // When firstMock.add('1-1'); firstMock.add('2-1'); firstMock.add('1-1'); firstMock.add('1-1'); firstMock.add('1-1'); firstMock.add('1-1'); firstMock.add('2-1'); // Then ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(1))).add('1-1'); ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(1))).add('2-1'); try { ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.never())).add(fflib_Match.stringStartsWith('1-')); System.Assert.fail('expected some exception because the method has been called'); } catch (fflib_ApexMocks.ApexMocksException e) { System.Assert.areEqual('EXPECTED COUNT: 0 in order' + '\nACTUAL COUNT: 4' + '\nMETHOD: fflib_MyList__sfdc_ApexStub.add(String)' + '\n---' + '\nACTUAL ARGS: ("1-1"), ("2-1"), ("1-1"), ("1-1"), ("1-1"), ("1-1"), ("2-1")' + '\n---' + '\nEXPECTED ARGS: [starts with "1-"]', e.getMessage(), 'Unexpected verify fail message'); } } @isTest static void thatVerifyThrowsExceptionWhenCallsIsInvochedFromStandardMock() { // Given fflib_MyList firstMock = (fflib_MyList)MY_MOCKS.mock(fflib_MyList.class); fflib_InOrder inOrder1 = new fflib_InOrder(MY_MOCKS, new List{ firstMock }); // When firstMock.add('1-1'); firstMock.add('2-1'); firstMock.add('1-1'); // Then try { ((fflib_MyList.IList) MY_MOCKS.verify(firstMock, MY_MOCKS.calls(1))).add('1-1'); System.Assert.fail('an exception was expected because the method is only implemented for the InOrder class'); } catch (fflib_ApexMocks.ApexMocksException mockExcept) { String expectedMessage = 'The calls() method is available only in the InOrder Verification.'; System.Assert.areEqual(expectedMessage, mockExcept.getMessage(), ' the error message is not as expected'); } } @isTest static void thatVerifyNoMoreInteractionsFails() { // Given fflib_MyList firstMock = (fflib_MyList)MY_MOCKS.mock(fflib_MyList.class); fflib_InOrder inOrder1 = new fflib_InOrder(MY_MOCKS, new List{ firstMock }); // When firstMock.add('1-1', '1-1', '1-1', '1-1'); firstMock.addMore('2-1'); firstMock.add('1-1'); ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(1))).add('1-1', '1-1', '1-1', '1-1'); // Then try { inOrder1.verifyNoMoreInteractions(); System.Assert.fail('an exception was expected because there are other interactions'); } catch (fflib_ApexMocks.ApexMocksException mockExcept) { String expectedMessage = 'No more Interactions were expected after the ' + fflib_MyList.getStubClassName() + '.add(String, String, String, String) method.'; System.Assert.areEqual(expectedMessage, mockExcept.getMessage(), ' the error message is not as expected'); } } @isTest static void thatVerifyNoMoreInteractionsFailsWhenOnLyOneMethodLeft() { // Given fflib_MyList firstMock = (fflib_MyList)MY_MOCKS.mock(fflib_MyList.class); fflib_InOrder inOrder1 = new fflib_InOrder(MY_MOCKS, new List{ firstMock }); // When firstMock.add('1-1', '1-1', '1-1', '1-1'); firstMock.addMore('2-1'); firstMock.add('1-1'); ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(1))).addMore('2-1'); // Then try { inOrder1.verifyNoMoreInteractions(); System.Assert.fail('an exception was expected because there are other interactions'); } catch (fflib_ApexMocks.ApexMocksException mockExcept) { String expectedMessage = 'No more Interactions were expected after the ' + fflib_MyList.getStubClassName() + '.addMore(String) method.'; System.Assert.areEqual(expectedMessage, mockExcept.getMessage(), ' the error message is not as expected'); } } @isTest static void thatVerifyNoMoreInteractionsPass() { // Given fflib_MyList firstMock = (fflib_MyList)MY_MOCKS.mock(fflib_MyList.class); fflib_MyList secondMock = (fflib_MyList)MY_MOCKS.mock(fflib_MyList.class); fflib_InOrder inOrder1 = new fflib_InOrder(MY_MOCKS, new List{ firstMock }); fflib_InOrder inOrder2 = new fflib_InOrder(MY_MOCKS, new List{ secondMock }); // When firstMock.add('1-1'); firstMock.add('2-1'); firstMock.add('1-1'); secondMock.add('1-1'); secondMock.add('1-1'); ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(1))).add('1-1'); ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(1))).add('2-1'); ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(1))).add('1-1'); inOrder1.verifyNoMoreInteractions(); ((fflib_MyList.IList)inOrder2.verify(secondMock, MY_MOCKS.calls(2))).add('1-1'); inOrder2.verifyNoMoreInteractions(); } @isTest static void thatVerifyNoMoreInteractionsFailsWhenNoInteracionOccurs() { // Given fflib_MyList firstMock = (fflib_MyList)MY_MOCKS.mock(fflib_MyList.class); fflib_InOrder inOrder1 = new fflib_InOrder(MY_MOCKS, new List{ firstMock }); // When firstMock.add('1-1'); firstMock.add('2-1'); firstMock.add('1-1'); // Then try { inOrder1.verifyNoMoreInteractions(); System.Assert.fail('an exception was expected because there are other interactions'); } catch (fflib_ApexMocks.ApexMocksException mockExcept) { String expectedMessage = 'No Interactions expected on this InOrder Mock instance!'; System.Assert.areEqual(expectedMessage, mockExcept.getMessage(), ' the error message is not as expected'); } } @isTest static void thatVerifyNoInteractionsFails() { // Given fflib_MyList firstMock = (fflib_MyList)MY_MOCKS.mock(fflib_MyList.class); fflib_InOrder inOrder1 = new fflib_InOrder(MY_MOCKS, new List{ firstMock }); // When firstMock.add('1-1'); firstMock.add('2-1'); firstMock.add('1-1'); // Then try { inOrder1.verifyNoInteractions(); System.Assert.fail('an exception was expected because there are other interactions'); } catch (fflib_ApexMocks.ApexMocksException mockExcept) { String expectedMessage = 'No Interactions expected on this InOrder Mock instance!'; System.Assert.areEqual(expectedMessage, mockExcept.getMessage(), ' the error message is not as expected'); } } @isTest static void thatVerifyNoInteractionsPass() { // Given fflib_MyList firstMock = (fflib_MyList)MY_MOCKS.mock(fflib_MyList.class); fflib_MyList secondMock = (fflib_MyList)MY_MOCKS.mock(fflib_MyList.class); fflib_InOrder inOrder1 = new fflib_InOrder(MY_MOCKS, new List{ firstMock }); // When secondMock.add('1-2'); //Then inOrder1.verifyNoInteractions(); } @isTest static void thatStrictVerificationCanBePerformed() { fflib_MyList firstMock = (fflib_MyList)MY_MOCKS.mock(fflib_MyList.class); fflib_InOrder inOrder1 = new fflib_InOrder(MY_MOCKS, new List{ firstMock }); // When firstMock.add('1-1'); firstMock.add('2-1'); firstMock.add('1-1'); firstMock.add('4-1'); // Then ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(1))).add('1-1'); ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(1))).add('2-1'); ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(1))).add('1-1'); ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(1))).add('4-1'); } @isTest static void thatMixedVerificationDoNotInterfierWithOtherImplementationChecking() { fflib_MyList firstMock = (fflib_MyList)MY_MOCKS.mock(fflib_MyList.class); fflib_InOrder inOrder1 = new fflib_InOrder(MY_MOCKS, new List{ firstMock }); // When firstMock.add('1-1'); firstMock.add('2-1'); firstMock.add('1-1'); firstMock.add('4-1'); // Then ((fflib_MyList.IList)MY_MOCKS.verify(firstMock, MY_MOCKS.times(2))).add('1-1'); ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(1))).add('1-1'); ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(1))).add('2-1'); ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(1))).add('1-1'); ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(1))).add('4-1'); ((fflib_MyList.IList)MY_MOCKS.verify(firstMock, MY_MOCKS.times(2))).add('1-1'); } @isTest static void thatVerifyAtLeastPassWithSameCallsOfAssertion() { // Given fflib_MyList firstMock = (fflib_MyList)MY_MOCKS.mock(fflib_MyList.class); fflib_InOrder inOrder1 = new fflib_InOrder(MY_MOCKS, new List{ firstMock }); // When firstMock.add('1-1'); //consumed by -> verify(firstMock, MY_MOCKS.calls(1))).add('1-1'); firstMock.add('2-1'); //consumed by -> verify(firstMock, MY_MOCKS.calls(1))).add('2-1'); firstMock.add('1-1'); firstMock.add('1-1'); firstMock.add('1-1'); //all consumed until there by -> verify(firstMock, MY_MOCKS.atLeast(3))).add('1-1'); firstMock.add('2-1'); //finally consumed by -> verify(firstMock, MY_MOCKS.calls(1))).add('2-1'); // Then ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(1))).add('1-1'); ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(1))).add('2-1'); ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.atLeast(3))).add('1-1'); ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(1))).add('2-1'); } @isTest static void thatVerifyAtLeastPassWithMoreCallsThenAsserted() { // Given fflib_MyList firstMock = (fflib_MyList)MY_MOCKS.mock(fflib_MyList.class); fflib_InOrder inOrder1 = new fflib_InOrder(MY_MOCKS, new List{ firstMock }); // When firstMock.add('1-1'); //consumed by -> verify(firstMock, MY_MOCKS.calls(1))).add('1-1'); firstMock.add('2-1'); //consumed by -> verify(firstMock, MY_MOCKS.calls(1))).add('2-1'); firstMock.add('1-1'); firstMock.add('1-1'); //it verifies until here, but firstMock.add('1-1'); //this is consumed as well firstMock.add('2-1'); //finally consumed by -> verify(firstMock, MY_MOCKS.calls(1))).add('2-1'); // Then ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(1))).add('1-1'); ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(1))).add('2-1'); ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.atLeast(2))).add('1-1'); ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(1))).add('2-1'); } @isTest static void thatVerifyAtLeastThrowsErrorIfCalledLessTimes() { // Given fflib_MyList firstMock = (fflib_MyList)MY_MOCKS.mock(fflib_MyList.class); fflib_InOrder inOrder1 = new fflib_InOrder(MY_MOCKS, new List{ firstMock }); // When firstMock.add('1-1'); //consumed by -> verify(firstMock, MY_MOCKS.calls(1))).add('1-1'); firstMock.add('2-1'); //consumed by -> verify(firstMock, MY_MOCKS.calls(1))).add('2-1'); firstMock.add('1-1'); firstMock.add('1-1'); firstMock.add('1-1'); //there are then only 3 calls available, the assert 4 would fail firstMock.add('2-1'); // Then ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(1))).add('1-1'); ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(1))).add('2-1'); try { ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.atLeast(4))).add('1-1'); System.Assert.fail('an exception was expected because the atLeast is asserting for 4 calls when instead there are only 3 not consumed calls'); } catch (fflib_ApexMocks.ApexMocksException mockExcept) { System.Assert.areEqual('EXPECTED COUNT: 4 in order' +'\nACTUAL COUNT: 3' +'\nMETHOD: fflib_MyList__sfdc_ApexStub.add(String)' +'\n---' +'\nACTUAL ARGS: ("1-1"), ("2-1"), ("1-1"), ("1-1"), ("1-1"), ("2-1")' +'\n---' +'\nEXPECTED ARGS: "1-1"', mockExcept.getMessage(), 'Unexpected verify fail message'); } } @isTest static void thatVerifyAtLeastConsumeAllTheInstances() { // Given fflib_MyList firstMock = (fflib_MyList)MY_MOCKS.mock(fflib_MyList.class); fflib_InOrder inOrder1 = new fflib_InOrder(MY_MOCKS, new List{ firstMock }); // When firstMock.add('1-1'); //consumed by -> verify(firstMock, MY_MOCKS.calls(1))).add('1-1'); firstMock.add('2-1'); //consumed by -> verify(firstMock, MY_MOCKS.calls(1))).add('2-1'); firstMock.add('1-1'); firstMock.add('1-1'); // the verify atLeast(2) it verifies until here, but it keep going through the instances firstMock.add('1-1'); firstMock.add('2-1'); //so this would fail because have to first consume all the instances of the ('1-1') firstMock.add('1-1'); firstMock.add('1-1'); ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(1))).add('1-1'); ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(1))).add('2-1'); ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.atLeast(2))).add('1-1'); // Then try { ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(1))).add('2-1'); System.Assert.fail('an exception was expected because the atLeast have consumed all the interactions of 1-1'); } catch (fflib_ApexMocks.ApexMocksException mockExcept) { System.Assert.areEqual('EXPECTED COUNT: 1 in order' +'\nACTUAL COUNT: 0' +'\nMETHOD: fflib_MyList__sfdc_ApexStub.add(String)' +'\n---' +'\nACTUAL ARGS: ("1-1"), ("2-1"), ("1-1"), ("1-1"), ("1-1"), ("2-1"), ("1-1"), ("1-1")' +'\n---' +'\nEXPECTED ARGS: "2-1"', mockExcept.getMessage(), 'Unexpected verify fail message'); } } @isTest static void thatVerifyAtLeastConsumeAllTheInstancesForOnlyTheMethodVerified() { // Given fflib_MyList firstMock = (fflib_MyList)MY_MOCKS.mock(fflib_MyList.class); fflib_InOrder inOrder1 = new fflib_InOrder(MY_MOCKS, new List{ firstMock }); // When firstMock.add('1-1'); firstMock.add('2-1'); firstMock.add('1-1'); firstMock.add('1-1'); firstMock.add('1-1'); firstMock.add('2-1'); // verify(firstMock, MY_MOCKS.atLeast(2))).add('2-1'); consume until here firstMock.add('1-1'); firstMock.add('1-1'); //those are then free for the second atLeast assertion // Then ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.atLeast(2))).add('2-1'); ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.atLeast(2))).add('1-1'); } @isTest static void thatVerifyAtLeastOnce() { // Given fflib_MyList firstMock = (fflib_MyList)MY_MOCKS.mock(fflib_MyList.class); fflib_InOrder inOrder1 = new fflib_InOrder(MY_MOCKS, new List{ firstMock }); // When firstMock.add('1-1'); firstMock.add('2-1'); firstMock.add('1-1'); ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.atLeastOnce())).add('1-1'); } @isTest static void thatVerifyAtLeastOnceConsumesInstancesUntilLastMethodVerified() { // Given fflib_MyList firstMock = (fflib_MyList)MY_MOCKS.mock(fflib_MyList.class); fflib_InOrder inOrder1 = new fflib_InOrder(MY_MOCKS, new List{ firstMock }); // When firstMock.add('1-1'); firstMock.add('2-1'); firstMock.add('1-1'); // consumed until there by -> verify(firstMock, MY_MOCKS.atLeastOnce())).add('1-1'); firstMock.add('2-1'); // free for another assertion ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.atLeastOnce())).add('1-1'); ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.atLeastOnce())).add('2-1'); } @isTest static void thatVerifyAtLeastOnceThrowsErrorIfCalledLessTimes() { // Given fflib_MyList firstMock = (fflib_MyList)MY_MOCKS.mock(fflib_MyList.class); fflib_InOrder inOrder1 = new fflib_InOrder(MY_MOCKS, new List{ firstMock }); // When firstMock.add('1-1'); firstMock.add('2-1'); firstMock.add('1-1'); // Then try { ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.atLeastOnce())).add('1-3'); System.Assert.fail('an exception was expected because the atLeastOnce is asserting for 1 calls when instead the method is not called at all with that argument'); } catch (fflib_ApexMocks.ApexMocksException mockExcept) { System.Assert.areEqual('EXPECTED COUNT: 1 in order' +'\nACTUAL COUNT: 0' +'\nMETHOD: fflib_MyList__sfdc_ApexStub.add(String)' +'\n---' +'\nACTUAL ARGS: ("1-1"), ("2-1"), ("1-1")' +'\n---' +'\nEXPECTED ARGS: "1-3"', mockExcept.getMessage(), 'Unexpected verify fail message'); } } @isTest static void thatVerifyAtLeastOnceConsumesAllTheInstances() { // Given fflib_MyList firstMock = (fflib_MyList)MY_MOCKS.mock(fflib_MyList.class); fflib_InOrder inOrder1 = new fflib_InOrder(MY_MOCKS, new List{ firstMock }); // When firstMock.add('1-1'); firstMock.add('2-1'); firstMock.add('1-1'); firstMock.add('2-1'); firstMock.add('1-1'); firstMock.add('1-1'); //all the instance have been consumed ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.atLeastOnce())).add('1-1'); // Then try { ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(1))).add('2-1'); System.Assert.fail('an exception was expected because the atLeast have consumed all the interactions of 1-1'); } catch (fflib_ApexMocks.ApexMocksException mockExcept) { System.Assert.areEqual('EXPECTED COUNT: 1 in order' +'\nACTUAL COUNT: 0' +'\nMETHOD: fflib_MyList__sfdc_ApexStub.add(String)' +'\n---' +'\nACTUAL ARGS: ("1-1"), ("2-1"), ("1-1"), ("2-1"), ("1-1"), ("1-1")' +'\n---' +'\nEXPECTED ARGS: "2-1"', mockExcept.getMessage(), 'Unexpected verify fail message'); } } @isTest static void thatVerifyTimes() { // Given fflib_MyList firstMock = (fflib_MyList)MY_MOCKS.mock(fflib_MyList.class); fflib_InOrder inOrder1 = new fflib_InOrder(MY_MOCKS, new List{ firstMock }); // When firstMock.add('1-1'); firstMock.add('2-1'); firstMock.add('1-1'); firstMock.add('1-1'); firstMock.add('1-1'); firstMock.add('2-1'); // Then ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(1))).add('1-1'); ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(1))).add('2-1'); ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.times(3))).add('1-1'); } @isTest static void thatVerifyTimesThrowsExceptionIfCalledMoreTimesThanExpected() { // Given fflib_MyList firstMock = (fflib_MyList)MY_MOCKS.mock(fflib_MyList.class); fflib_InOrder inOrder1 = new fflib_InOrder(MY_MOCKS, new List{ firstMock }); // When firstMock.add('1-1'); firstMock.add('2-1'); firstMock.add('1-1'); firstMock.add('1-1'); firstMock.add('1-1'); firstMock.add('2-1'); // Then ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(1))).add('1-1'); ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(1))).add('2-1'); try { ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.times(2))).add('1-1'); System.Assert.fail('exception expected because the method is called more times than expected in the verification'); } catch (fflib_ApexMocks.ApexMocksException mockExcept) { System.Assert.areEqual('EXPECTED COUNT: 2 in order' + '\nACTUAL COUNT: 3' + '\nMETHOD: fflib_MyList__sfdc_ApexStub.add(String)' + '\n---' + '\nACTUAL ARGS: ("1-1"), ("2-1"), ("1-1"), ("1-1"), ("1-1"), ("2-1")' + '\n---' + '\nEXPECTED ARGS: "1-1"', mockExcept.getMessage(), 'Unexpected verify fail message'); } } @isTest static void thatVerifyTimesThrowsExceptionIfCalledLessTimesThanExpected() { // Given fflib_MyList firstMock = (fflib_MyList)MY_MOCKS.mock(fflib_MyList.class); fflib_InOrder inOrder1 = new fflib_InOrder(MY_MOCKS, new List{ firstMock }); // When firstMock.add('1-1'); firstMock.add('2-1'); firstMock.add('1-1'); firstMock.add('1-1'); firstMock.add('1-1'); firstMock.add('2-1'); // Then ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(1))).add('1-1'); ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(1))).add('2-1'); try { ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.times(4))).add('1-1'); System.Assert.fail('exception expected because the method is called more times than expected in the verification'); } catch (fflib_ApexMocks.ApexMocksException mockExcept) { System.Assert.areEqual('EXPECTED COUNT: 4 in order' + '\nACTUAL COUNT: 3' + '\nMETHOD: fflib_MyList__sfdc_ApexStub.add(String)' + '\n---' + '\nACTUAL ARGS: ("1-1"), ("2-1"), ("1-1"), ("1-1"), ("1-1"), ("2-1")' + '\n---' + '\nEXPECTED ARGS: "1-1"', mockExcept.getMessage(), 'Unexpected verify fail message'); } } @isTest static void thatVerifyTimesPassWhenAnotherMethodIsCalledBetweenMethodsCalls() { // Given fflib_MyList firstMock = (fflib_MyList)MY_MOCKS.mock(fflib_MyList.class); fflib_InOrder inOrder1 = new fflib_InOrder(MY_MOCKS, new List{ firstMock }); // When firstMock.add('1-1'); firstMock.add('2-1'); firstMock.add('1-1'); firstMock.add('1-1'); firstMock.add('1-1'); firstMock.add('2-1'); firstMock.add('1-1'); firstMock.add('2-1'); // Then ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(1))).add('1-1'); ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(1))).add('2-1'); ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.times(4))).add('1-1'); ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.times(1))).add('2-1'); } @isTest static void thatVerifyTimesPassWhenAnotherMethodIsCalledBetweenMethodsCalls2() { // Given fflib_MyList firstMock = (fflib_MyList)MY_MOCKS.mock(fflib_MyList.class); fflib_InOrder inOrder1 = new fflib_InOrder(MY_MOCKS, new List{ firstMock }); // When firstMock.add('1-1'); firstMock.add('2-1'); firstMock.add('1-1'); firstMock.add('1-1'); firstMock.add('1-1'); firstMock.add('2-1'); firstMock.add('1-1'); firstMock.add('2-1'); // Then ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(1))).add('1-1'); ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(1))).add('2-1'); ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.times(3))).add('1-1'); ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.times(1))).add('2-1'); ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.times(1))).add('1-1'); } @isTest static void thatVerifyTimesPassWhenAnotherMethodIsCalledBetweenMethodsCalls3() { // Given fflib_MyList firstMock = (fflib_MyList)MY_MOCKS.mock(fflib_MyList.class); fflib_InOrder inOrder1 = new fflib_InOrder(MY_MOCKS, new List{ firstMock }); // When firstMock.add('1-1'); firstMock.add('2-1'); firstMock.add('1-1'); firstMock.add('1-1'); firstMock.add('1-1'); firstMock.add('2-1'); firstMock.add('1-1'); firstMock.add('1-1'); firstMock.add('2-1'); firstMock.add('1-1'); // Then ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(1))).add('1-1'); ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(1))).add('2-1'); ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.times(3))).add('1-1'); ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.times(1))).add('2-1'); ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.times(2))).add('1-1'); ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.times(1))).add('2-1'); ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.times(1))).add('1-1'); } @isTest static void thatVerifyTimesPassWhenAnotherMethodIsCalledBetweenMethodsCalls4() { // Given fflib_MyList firstMock = (fflib_MyList)MY_MOCKS.mock(fflib_MyList.class); fflib_InOrder inOrder1 = new fflib_InOrder(MY_MOCKS, new List{ firstMock }); // When firstMock.add('1-1'); firstMock.add('2-1'); firstMock.add('1-1'); firstMock.add('1-1'); firstMock.add('1-1'); firstMock.add('2-1'); firstMock.add('1-1'); firstMock.add('1-1'); firstMock.add('2-1'); firstMock.add('1-1'); // Then ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(1))).add('1-1'); ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(1))).add('2-1'); ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.times(5))).add('1-1'); ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.times(1))).add('2-1'); ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.times(1))).add('1-1'); } @isTest static void thatVerifyTimesThrowsExceptionWhenAnotherMethodIsCalledBetweenMethodsCalls() { // Given fflib_MyList firstMock = (fflib_MyList)MY_MOCKS.mock(fflib_MyList.class); fflib_InOrder inOrder1 = new fflib_InOrder(MY_MOCKS, new List{ firstMock }); // When firstMock.add('1-1'); firstMock.add('2-1'); firstMock.add('1-1'); firstMock.add('1-1'); firstMock.add('1-1'); firstMock.add('2-1'); firstMock.add('1-1'); firstMock.add('2-1'); // Then ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(1))).add('1-1'); ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(1))).add('2-1'); try { ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.times(5))).add('1-1'); System.Assert.fail('exception expected because the method is called more times than expected in the verification'); } catch (fflib_ApexMocks.ApexMocksException mockExcept) { System.Assert.areEqual('EXPECTED COUNT: 5 in order' + '\nACTUAL COUNT: 4' + '\nMETHOD: fflib_MyList__sfdc_ApexStub.add(String)' + '\n---' + '\nACTUAL ARGS: ("1-1"), ("2-1"), ("1-1"), ("1-1"), ("1-1"), ("2-1"), ("1-1"), ("2-1")' + '\n---' + '\nEXPECTED ARGS: "1-1"', mockExcept.getMessage(), 'Unexpected verify fail message'); } } @isTest static void thatStrictVerificationCanBeEnforced() { // Given fflib_MyList firstMock = (fflib_MyList)MY_MOCKS.mock(fflib_MyList.class); fflib_InOrder inOrder1 = new fflib_InOrder(MY_MOCKS, new List{ firstMock }); // When firstMock.add('1-1'); firstMock.add('2-1'); firstMock.add('1-1'); firstMock.add('1-1'); firstMock.add('1-1'); firstMock.add('2-1'); firstMock.add('1-1'); firstMock.add('2-1'); // Then ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.times(1))).add('1-1'); ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.times(1))).add('2-1'); ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.times(3))).add('1-1'); ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.times(1))).add('2-1'); ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.times(1))).add('1-1'); ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.times(1))).add('2-1'); } @isTest static void thatTimesOneIsTheDefaultVerification() { // Given fflib_MyList firstMock = (fflib_MyList)MY_MOCKS.mock(fflib_MyList.class); fflib_InOrder inOrder1 = new fflib_InOrder(MY_MOCKS, new List{ firstMock }); // When firstMock.add('1-1'); firstMock.add('2-1'); firstMock.add('1-1'); firstMock.add('1-1'); firstMock.add('1-1'); firstMock.add('2-1'); firstMock.add('1-1'); firstMock.add('2-1'); // Then ((fflib_MyList.IList)inOrder1.verify(firstMock)).add('1-1'); ((fflib_MyList.IList)inOrder1.verify(firstMock)).add('2-1'); try { ((fflib_MyList.IList)inOrder1.verify(firstMock)).add('1-1'); System.Assert.fail('exception expected because the method is called more times than expected in the verification'); } catch (fflib_ApexMocks.ApexMocksException mockExcept) { System.Assert.areEqual('EXPECTED COUNT: 1 in order' +'\nACTUAL COUNT: 4' +'\nMETHOD: fflib_MyList__sfdc_ApexStub.add(String)' +'\n---' +'\nACTUAL ARGS: ("1-1"), ("2-1"), ("1-1"), ("1-1"), ("1-1"), ("2-1"), ("1-1"), ("2-1")' +'\n---' +'\nEXPECTED ARGS: "1-1"', mockExcept.getMessage(), 'Unexpected verify fail message'); } } @isTest static void thatWithOldNotation() { // Given fflib_MyList firstMock = (fflib_MyList)MY_MOCKS.mock(fflib_MyList.class); fflib_InOrder inOrder1 = new fflib_InOrder(MY_MOCKS, new List{ firstMock }); // When firstMock.add('1-1'); firstMock.add('2-1'); firstMock.add('1-1'); firstMock.add('1-1'); firstMock.add('1-1'); firstMock.add('2-1'); // Then ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(1))).add('1-1'); ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(1))).add('2-1'); ((fflib_MyList.IList)inOrder1.verify(firstMock, 3)).add('1-1'); } @isTest static void thatWithOldNotationThrowsExceptionIfCalledMoreTimesThanExpected() { // Given fflib_MyList firstMock = (fflib_MyList)MY_MOCKS.mock(fflib_MyList.class); fflib_InOrder inOrder1 = new fflib_InOrder(MY_MOCKS, new List{ firstMock }); // When firstMock.add('1-1'); firstMock.add('2-1'); firstMock.add('1-1'); firstMock.add('1-1'); firstMock.add('1-1'); firstMock.add('2-1'); // Then ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(1))).add('1-1'); ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(1))).add('2-1'); try { ((fflib_MyList.IList)inOrder1.verify(firstMock, 2)).add('1-1'); System.Assert.fail('exception expected because the method is called more times than expected in the verification'); } catch (fflib_ApexMocks.ApexMocksException mockExcept) { System.Assert.areEqual('EXPECTED COUNT: 2 in order' + '\nACTUAL COUNT: 3' + '\nMETHOD: fflib_MyList__sfdc_ApexStub.add(String)' + '\n---' + '\nACTUAL ARGS: ("1-1"), ("2-1"), ("1-1"), ("1-1"), ("1-1"), ("2-1")' + '\n---' + '\nEXPECTED ARGS: "1-1"', mockExcept.getMessage(), 'Unexpected verify fail message'); } } @isTest static void thatWithOldNotationThrowsExceptionIfCalledLessTimesThanExpected() { // Given fflib_MyList firstMock = (fflib_MyList)MY_MOCKS.mock(fflib_MyList.class); fflib_InOrder inOrder1 = new fflib_InOrder(MY_MOCKS, new List{ firstMock }); // When firstMock.add('1-1'); firstMock.add('2-1'); firstMock.add('1-1'); firstMock.add('1-1'); firstMock.add('1-1'); firstMock.add('2-1'); // Then ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(1))).add('1-1'); ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(1))).add('2-1'); try { ((fflib_MyList.IList)inOrder1.verify(firstMock, 4)).add('1-1'); System.Assert.fail('exception expected because the method is called more times than expected in the verification'); } catch (fflib_ApexMocks.ApexMocksException mockExcept) { System.Assert.areEqual('EXPECTED COUNT: 4 in order' + '\nACTUAL COUNT: 3' + '\nMETHOD: fflib_MyList__sfdc_ApexStub.add(String)' + '\n---' + '\nACTUAL ARGS: ("1-1"), ("2-1"), ("1-1"), ("1-1"), ("1-1"), ("2-1")' + '\n---' + '\nEXPECTED ARGS: "1-1"', mockExcept.getMessage(), 'Unexpected verify fail message'); } } @isTest static void thatWithOldNotationPassWhenAnotherMethodIsCalledBetweenMethodsCalls() { // Given fflib_MyList firstMock = (fflib_MyList)MY_MOCKS.mock(fflib_MyList.class); fflib_InOrder inOrder1 = new fflib_InOrder(MY_MOCKS, new List{ firstMock }); // When firstMock.add('1-1'); firstMock.add('2-1'); firstMock.add('1-1'); firstMock.add('1-1'); firstMock.add('1-1'); firstMock.add('2-1'); firstMock.add('1-1'); firstMock.add('2-1'); // Then ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(1))).add('1-1'); ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(1))).add('2-1'); ((fflib_MyList.IList)inOrder1.verify(firstMock, 4)).add('1-1'); } @isTest static void thatWithOldNotationThrowsExceptionWhenAnotherMethodIsCalledBetweenMethodsCalls() { // Given fflib_MyList firstMock = (fflib_MyList)MY_MOCKS.mock(fflib_MyList.class); fflib_InOrder inOrder1 = new fflib_InOrder(MY_MOCKS, new List{ firstMock }); // When firstMock.add('1-1'); firstMock.add('2-1'); firstMock.add('1-1'); firstMock.add('1-1'); firstMock.add('1-1'); firstMock.add('2-1'); firstMock.add('1-1'); firstMock.add('2-1'); // Then ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(1))).add('1-1'); ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(1))).add('2-1'); try { ((fflib_MyList.IList)inOrder1.verify(firstMock, 5)).add('1-1'); System.Assert.fail('exception expected because the method is called more times than expected in the verification'); } catch (fflib_ApexMocks.ApexMocksException mockExcept) { System.Assert.areEqual('EXPECTED COUNT: 5 in order' + '\nACTUAL COUNT: 4' + '\nMETHOD: fflib_MyList__sfdc_ApexStub.add(String)' + '\n---' + '\nACTUAL ARGS: ("1-1"), ("2-1"), ("1-1"), ("1-1"), ("1-1"), ("2-1"), ("1-1"), ("2-1")' + '\n---' + '\nEXPECTED ARGS: "1-1"', mockExcept.getMessage(), 'Unexpected verify fail message'); } } @isTest static void thatStrictVerificationCanBeEnforcedWithOldNotation() { // Given fflib_MyList firstMock = (fflib_MyList)MY_MOCKS.mock(fflib_MyList.class); fflib_InOrder inOrder1 = new fflib_InOrder(MY_MOCKS, new List{ firstMock }); // When firstMock.add('1-1'); firstMock.add('2-1'); firstMock.add('1-1'); firstMock.add('1-1'); firstMock.add('1-1'); firstMock.add('2-1'); firstMock.add('1-1'); firstMock.add('2-1'); // Then ((fflib_MyList.IList)inOrder1.verify(firstMock, 1)).add('1-1'); ((fflib_MyList.IList)inOrder1.verify(firstMock, 1)).add('2-1'); ((fflib_MyList.IList)inOrder1.verify(firstMock, 3)).add('1-1'); ((fflib_MyList.IList)inOrder1.verify(firstMock, 1)).add('2-1'); ((fflib_MyList.IList)inOrder1.verify(firstMock, 1)).add('1-1'); ((fflib_MyList.IList)inOrder1.verify(firstMock, 1)).add('2-1'); } @isTest static void thatStrictVerificationCanBeEnforcedWithOldNotationUsingDefaultTimesOne() { // Given fflib_MyList firstMock = (fflib_MyList)MY_MOCKS.mock(fflib_MyList.class); fflib_InOrder inOrder1 = new fflib_InOrder(MY_MOCKS, new List{ firstMock }); // When firstMock.add('1-1'); firstMock.add('2-1'); firstMock.add('1-1'); firstMock.add('1-1'); firstMock.add('1-1'); firstMock.add('2-1'); firstMock.add('1-1'); firstMock.add('2-1'); // Then ((fflib_MyList.IList)inOrder1.verify(firstMock)).add('1-1'); ((fflib_MyList.IList)inOrder1.verify(firstMock)).add('2-1'); ((fflib_MyList.IList)inOrder1.verify(firstMock, 3)).add('1-1'); ((fflib_MyList.IList)inOrder1.verify(firstMock)).add('2-1'); ((fflib_MyList.IList)inOrder1.verify(firstMock)).add('1-1'); ((fflib_MyList.IList)inOrder1.verify(firstMock)).add('2-1'); } @isTest static void thatVerifyAtLeastConsumesAllTheInstances2() { // Given fflib_MyList firstMock = (fflib_MyList)MY_MOCKS.mock(fflib_MyList.class); fflib_InOrder inOrder1 = new fflib_InOrder(MY_MOCKS, new List{ firstMock }); //When firstMock.add('1-1'); firstMock.add('1-1'); firstMock.add('1-1'); firstMock.add('2-1'); firstMock.add('2-1'); firstMock.add('2-1'); firstMock.add('2-1'); firstMock.add('2-1'); firstMock.add('1-1'); // Then ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.atLeast(2))).add('1-1'); try { ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(1))).add('2-1'); System.Assert.fail('exception expected because the atLeast have consumed all the calls'); } catch (fflib_ApexMocks.ApexMocksException mockExcept) { System.Assert.areEqual('EXPECTED COUNT: 1 in order' +'\nACTUAL COUNT: 0' +'\nMETHOD: fflib_MyList__sfdc_ApexStub.add(String)' +'\n---' +'\nACTUAL ARGS: ("1-1"), ("1-1"), ("1-1"), ("2-1"), ("2-1"), ("2-1"), ("2-1"), ("2-1"), ("1-1")' +'\n---' +'\nEXPECTED ARGS: "2-1"', mockExcept.getMessage(), 'Unexpected verify fail message'); } } @isTest static void verifyAtLeastAndCapture() { // Given fflib_MyList firstMock = (fflib_MyList)MY_MOCKS.mock(fflib_MyList.class); fflib_InOrder inOrder1 = new fflib_InOrder(MY_MOCKS, new List{ firstMock }); //When firstMock.get2(1, '1-1'); firstMock.get2(2, '2-1'); firstMock.get2(1, '3-1'); firstMock.get2(1, '4-1'); firstMock.get2(2, '5-1'); fflib_ArgumentCaptor argument = fflib_ArgumentCaptor.forClass(String.class); ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.atLeast(2))).get2( fflib_Match.eqInteger(1), (String) argument.capture()); System.Assert.areEqual('4-1', (string) argument.getValue(), 'the last value captured is not as expected'); } @isTest static void verifyTimesAndCaptor() { // Given fflib_MyList firstMock = (fflib_MyList)MY_MOCKS.mock(fflib_MyList.class); fflib_InOrder inOrder1 = new fflib_InOrder(MY_MOCKS, new List{ firstMock }); //When firstMock.get2(1, '1-1'); firstMock.get2(2, '1-2'); firstMock.get2(1, '2-1'); firstMock.get2(2, '2-2'); firstMock.get2(1, '3-1'); firstMock.get2(2, '3-2'); firstMock.get2(1, '4-1'); firstMock.get2(2, '4-2'); firstMock.get2(1, '5-1'); firstMock.get2(2, '5-2'); fflib_ArgumentCaptor argument = fflib_ArgumentCaptor.forClass(String.class); ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.times(5))).get2(fflib_Match.eqInteger(1), (String) argument.capture()); System.Assert.areEqual('5-1', (string) argument.getValue(), 'the last value captured is not as expected'); } @isTest static void verifyCallsAndCapture() { // Given fflib_MyList firstMock = (fflib_MyList)MY_MOCKS.mock(fflib_MyList.class); fflib_InOrder inOrder1 = new fflib_InOrder(MY_MOCKS, new List{ firstMock }); //When firstMock.get2(1, '1-1'); firstMock.get2(2, '1-2'); firstMock.get2(1, '2-1'); firstMock.get2(2, '2-2'); firstMock.get2(1, '3-1'); firstMock.get2(2, '3-2'); firstMock.get2(1, '4-1'); firstMock.get2(2, '4-2'); firstMock.get2(1, '5-1'); firstMock.get2(2, '5-2'); fflib_ArgumentCaptor argument = fflib_ArgumentCaptor.forClass(String.class); ((fflib_MyList.IList)inOrder1.verify(firstMock, MY_MOCKS.calls(2))).get2(fflib_Match.eqInteger(1), (String) argument.capture()); System.Assert.areEqual('2-1', (string) argument.getValue(), 'the last value captured is not as expected'); } } ================================================ FILE: sfdx-source/apex-mocks/test/classes/fflib_InOrderTest.cls-meta.xml ================================================ 63.0 Active ================================================ FILE: sfdx-source/apex-mocks/test/classes/fflib_InheritorTest.cls ================================================ /* * Copyright (c) 2016-2017 FinancialForce.com, inc. All rights reserved. */ @isTest public class fflib_InheritorTest { @isTest public static void canInstantiateMultipleInterfaceInheritor() { fflib_ApexMocks mocks = new fflib_ApexMocks(); Object inheritor = mocks.mock(fflib_Inheritor.class); System.Assert.isInstanceOfType(inheritor, fflib_Inheritor.IA.class); System.Assert.isInstanceOfType(inheritor, fflib_Inheritor.IB.class); System.Assert.isInstanceOfType(inheritor, fflib_Inheritor.IC.class); } @isTest public static void canStubMultipleInterfaceInheritor() { fflib_ApexMocks mocks = new fflib_ApexMocks(); fflib_Inheritor inheritor = (fflib_Inheritor)mocks.mock(fflib_Inheritor.class); mocks.startStubbing(); mocks.when(inheritor.doA()).thenReturn('Did not do A'); mocks.when(inheritor.doB()).thenReturn('Did not do B'); mocks.when(inheritor.doC()).thenReturn('Did not do C'); mocks.stopStubbing(); System.Assert.areEqual('Did not do A', inheritor.doA()); System.Assert.areEqual('Did not do B', inheritor.doB()); System.Assert.areEqual('Did not do C', inheritor.doC()); } } ================================================ FILE: sfdx-source/apex-mocks/test/classes/fflib_InheritorTest.cls-meta.xml ================================================ 63.0 ================================================ FILE: sfdx-source/apex-mocks/test/classes/fflib_MatchTest.cls ================================================ /** * Copyright (c) 2014-2016, FinancialForce.com, inc * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * - Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * - Neither the name of the FinancialForce.com, inc nor the names of its contributors * may be used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ @isTest public with sharing class fflib_MatchTest { @isTest private static void whenMatchesAllArgsWithOneMatchReturnsTrue() { //Given fflib_MethodArgValues argValues = new fflib_MethodArgValues(new List{ null }); List targetMatchers = new List{ new AlwaysMatch() }; //When Boolean match = fflib_Match.matchesAllArgs(argValues, targetMatchers); //Then System.Assert.isTrue(match); } @isTest private static void whenMatchesAllArgsWithManyMatchesReturnsTrue() { //Given fflib_MethodArgValues argValues = new fflib_MethodArgValues(new List{ null, null, null, null }); List targetMatchers = new List{ new AlwaysMatch(), new AlwaysMatch(), new AlwaysMatch(), new AlwaysMatch() }; //When Boolean match = fflib_Match.matchesAllArgs(argValues, targetMatchers); //Then System.Assert.isTrue(match); } @isTest private static void whenMatchesAllArgsWithOneMismatchReturnsFalse() { //Given fflib_MethodArgValues argValues = new fflib_MethodArgValues(new List{ null }); List targetMatchers = new List{ new NeverMatch() }; //When Boolean match = fflib_Match.matchesAllArgs(argValues, targetMatchers); //Then System.Assert.isFalse(match); } @isTest private static void whenMatchesAllArgsWithManyMismatchesReturnsFalse() { //Given fflib_MethodArgValues argValues = new fflib_MethodArgValues(new List{ null, null, null, null }); List targetMatchers = new List{ new NeverMatch(), new NeverMatch(), new NeverMatch(), new NeverMatch() }; //When Boolean match = fflib_Match.matchesAllArgs(argValues, targetMatchers); //Then System.Assert.isFalse(match); } @isTest private static void whenMatchesAllArgsWithMatchesAndMismatchesReturnsFalse() { //Given fflib_MethodArgValues argValues = new fflib_MethodArgValues(new List{ null, null, null, null }); List targetMatchers = new List{ new AlwaysMatch(), new AlwaysMatch(), new NeverMatch(), new AlwaysMatch() }; //When Boolean match = fflib_Match.matchesAllArgs(argValues, targetMatchers); //Then System.Assert.isFalse(match); } @isTest private static void whenMatchesAllArgsWithNullMethodArgsThrowsException() { //Given fflib_MethodArgValues methodArg = null; List targetMatchers = new List{ new AlwaysMatch() }; //When try { fflib_Match.matchesAllArgs(methodArg, targetMatchers); System.Assert.fail('Expected exception'); } catch (fflib_ApexMocks.ApexMocksException e) { //Then System.Assert.areEqual('MethodArgs cannot be null', e.getMessage()); } } @isTest private static void whenMatchesAllArgsWithNullMethodArgsArgValuesThrowsException() { //Given fflib_MethodArgValues methodArg = new fflib_MethodArgValues(null); List targetMatchers = new List{ new AlwaysMatch() }; //When try { fflib_Match.matchesAllArgs(methodArg, targetMatchers); System.Assert.fail('Expected exception'); } catch (fflib_ApexMocks.ApexMocksException e) { //Then System.Assert.areEqual('MethodArgs.argValues cannot be null', e.getMessage()); } } @isTest private static void whenMatchesAllArgsWithNullMatchersThrowsException() { //Given fflib_MethodArgValues methodArg = new fflib_MethodArgValues(new List{ 'Test' }); List targetMatchers = null; //When try { fflib_Match.matchesAllArgs(methodArg, targetMatchers); System.Assert.fail('Expected exception'); } catch (fflib_ApexMocks.ApexMocksException e) { //Then System.Assert.areEqual('Matchers cannot be null', e.getMessage()); } } @isTest private static void whenMatchesAllArgsWithDifferentSizeArgValuesAndMatchersThrowsException() { //Given fflib_MethodArgValues methodArg = new fflib_MethodArgValues(new List{ 'Test' }); List targetMatchers = new List{ new AlwaysMatch(), new AlwaysMatch() }; //When try { fflib_Match.matchesAllArgs(methodArg, targetMatchers); System.Assert.fail('Expected exception'); } catch (fflib_ApexMocks.ApexMocksException e) { //Then String expectedMessage = 'MethodArgs and matchers must have the same count' + ', MethodArgs: (' + methodArg.argValues.size() + ') ' + methodArg.argValues + ', Matchers: (' + targetMatchers.size() + ') ' + targetMatchers; System.Assert.areEqual(expectedMessage, e.getMessage()); } } @isTest private static void whenMatchesWithOneMatcherSetsMatchingToTrue() { //Given fflib_IMatcher matcher = new AlwaysMatch(); //When fflib_Match.matches(matcher); //Then System.Assert.isTrue(fflib_Match.Matching); } @isTest private static void whenMatchesWithOneMatcherRegistersMatcher() { //Given fflib_IMatcher matcher = new AlwaysMatch(); //When fflib_Match.matches(matcher); //Then List registeredMatchers = fflib_Match.getAndClearMatchers(1); System.Assert.areNotEqual(null, registeredMatchers); System.Assert.areEqual(1, registeredMatchers.size()); System.Assert.areEqual(matcher, registeredMatchers[0]); } @isTest private static void whenMatchesWithOneMatcherReturnsNull() { //Given fflib_IMatcher matcher = new AlwaysMatch(); //When Object retval = fflib_Match.matches(matcher); //Then System.Assert.areEqual(null, retval); } @isTest private static void allOfWithNoArgsThrowsException() { //Given/When try { Object x = fflib_Match.allOf((List)null); System.Assert.fail('Expected exception'); } catch (fflib_ApexMocks.ApexMocksException e) { //Then System.Assert.areEqual('Must register matchers to combine', e.getMessage()); } } @isTest private static void allOfWithEmptyArgsThrowsException() { //Given/When try { Object x = fflib_Match.allOf(new List{}); System.Assert.fail('Expected exception'); } catch (fflib_ApexMocks.ApexMocksException e) { //Then System.Assert.areEqual('Must register matchers to combine', e.getMessage()); } } @isTest private static void allOfWithoutRegisteringInnerMatchersThrowsException() { //Given/When try { //Should be using fflib_Match.allOf(new List{ fflib_Match.myMatcher('Hello') }) //to register the inner matcher. Object x = fflib_Match.allOf(new List{ 'Hello' }); System.Assert.fail('Expected exception'); } catch (fflib_ApexMocks.ApexMocksException e) { //Then String expectedMessage = 'Error reclaiming inner matchers for combined matcher. ' + 'Wanted 1 matchers but only got ' + new List(); System.Assert.areEqual(expectedMessage, e.getMessage()); } } @isTest private static void allOfWith2ArgsRegistersCorrectMatcherType() { //Given/When Object x = fflib_Match.allOf(fflib_Match.eq('hello1'), fflib_Match.eq('hello2')); //Then List registeredMatchers = fflib_Match.getAndClearMatchers(1); System.Assert.areNotEqual(null, registeredMatchers); System.Assert.areEqual(1, registeredMatchers.size()); System.Assert.isInstanceOfType(registeredMatchers[0], fflib_MatcherDefinitions.Combined.class); } @isTest private static void allOfWith3ArgsRegistersCorrectMatcherType() { //Given/When Object x = fflib_Match.allOf(fflib_Match.eq('hello1'), fflib_Match.eq('hello2'), fflib_Match.eq('hello3')); //Then List registeredMatchers = fflib_Match.getAndClearMatchers(1); System.Assert.areNotEqual(null, registeredMatchers); System.Assert.areEqual(1, registeredMatchers.size()); System.Assert.isInstanceOfType(registeredMatchers[0], fflib_MatcherDefinitions.Combined.class); } @isTest private static void allOfWith4ArgsRegistersCorrectMatcherType() { //Given/When Object x = fflib_Match.allOf(fflib_Match.eq('hello1'), fflib_Match.eq('hello2'), fflib_Match.eq('hello3'), fflib_Match.eq('hello4')); //Then List registeredMatchers = fflib_Match.getAndClearMatchers(1); System.Assert.areNotEqual(null, registeredMatchers); System.Assert.areEqual(1, registeredMatchers.size()); System.Assert.isInstanceOfType(registeredMatchers[0], fflib_MatcherDefinitions.Combined.class); } @isTest private static void allOfWithListArgsRegistersCorrectMatcherType() { //Given/When Object x = fflib_Match.allOf(new List{ fflib_Match.eq('hello') }); //Then List registeredMatchers = fflib_Match.getAndClearMatchers(1); System.Assert.areNotEqual(null, registeredMatchers); System.Assert.areEqual(1, registeredMatchers.size()); System.Assert.isInstanceOfType(registeredMatchers[0], fflib_MatcherDefinitions.Combined.class); } @isTest private static void anyOfWith2ArgsRegistersCorrectMatcherType() { //Given/When Object x = fflib_Match.anyOf(fflib_Match.eq('hello1'), fflib_Match.eq('hello2')); //Then List registeredMatchers = fflib_Match.getAndClearMatchers(1); System.Assert.areNotEqual(null, registeredMatchers); System.Assert.areEqual(1, registeredMatchers.size()); System.Assert.isInstanceOfType(registeredMatchers[0], fflib_MatcherDefinitions.Combined.class); } @isTest private static void anyOfWith3ArgsRegistersCorrectMatcherType() { //Given/When Object x = fflib_Match.anyOf(fflib_Match.eq('hello1'), fflib_Match.eq('hello2'), fflib_Match.eq('hello3')); //Then List registeredMatchers = fflib_Match.getAndClearMatchers(1); System.Assert.areNotEqual(null, registeredMatchers); System.Assert.areEqual(1, registeredMatchers.size()); System.Assert.isInstanceOfType(registeredMatchers[0], fflib_MatcherDefinitions.Combined.class); } @isTest private static void anyOfWith4ArgsRegistersCorrectMatcherType() { //Given/When Object x = fflib_Match.anyOf(fflib_Match.eq('hello1'), fflib_Match.eq('hello2'), fflib_Match.eq('hello3'), fflib_Match.eq('hello4')); //Then List registeredMatchers = fflib_Match.getAndClearMatchers(1); System.Assert.areNotEqual(null, registeredMatchers); System.Assert.areEqual(1, registeredMatchers.size()); System.Assert.isInstanceOfType(registeredMatchers[0], fflib_MatcherDefinitions.Combined.class); } @isTest private static void anyOfWithListArgsRegistersCorrectMatcherType() { //Given/When Object x = fflib_Match.anyOf(new List{ fflib_Match.eq('hello') }); //Then List registeredMatchers = fflib_Match.getAndClearMatchers(1); System.Assert.areNotEqual(null, registeredMatchers); System.Assert.areEqual(1, registeredMatchers.size()); System.Assert.isInstanceOfType(registeredMatchers[0], fflib_MatcherDefinitions.Combined.class); } @isTest private static void isNotRegistersCorrectMatcherType() { //Given/When Object x = fflib_Match.isNot(fflib_Match.eq('hello1')); //Then List registeredMatchers = fflib_Match.getAndClearMatchers(1); System.Assert.areNotEqual(null, registeredMatchers); System.Assert.areEqual(1, registeredMatchers.size()); System.Assert.isInstanceOfType(registeredMatchers[0], fflib_MatcherDefinitions.Combined.class); } @isTest private static void noneOfWith2ArgsRegistersCorrectMatcherType() { //Given/When Object x = fflib_Match.noneOf(fflib_Match.eq('hello1'), fflib_Match.eq('hello2')); //Then List registeredMatchers = fflib_Match.getAndClearMatchers(1); System.Assert.areNotEqual(null, registeredMatchers); System.Assert.areEqual(1, registeredMatchers.size()); System.Assert.isInstanceOfType(registeredMatchers[0], fflib_MatcherDefinitions.Combined.class); } @isTest private static void noneOfWith3ArgsRegistersCorrectMatcherType() { //Given/When Object x = fflib_Match.noneOf(fflib_Match.eq('hello1'), fflib_Match.eq('hello2'), fflib_Match.eq('hello3')); //Then List registeredMatchers = fflib_Match.getAndClearMatchers(1); System.Assert.areNotEqual(null, registeredMatchers); System.Assert.areEqual(1, registeredMatchers.size()); System.Assert.isInstanceOfType(registeredMatchers[0], fflib_MatcherDefinitions.Combined.class); } @isTest private static void noneOfWith4ArgsRegistersCorrectMatcherType() { //Given/When Object x = fflib_Match.noneOf(fflib_Match.eq('hello1'), fflib_Match.eq('hello2'), fflib_Match.eq('hello3'), fflib_Match.eq('hello4')); //Then List registeredMatchers = fflib_Match.getAndClearMatchers(1); System.Assert.areNotEqual(null, registeredMatchers); System.Assert.areEqual(1, registeredMatchers.size()); System.Assert.isInstanceOfType(registeredMatchers[0], fflib_MatcherDefinitions.Combined.class); } @isTest private static void noneOfWithListArgsRegistersCorrectMatcherType() { //Given/When Object x = fflib_Match.noneOf(new List{ fflib_Match.eq('hello') }); //Then List registeredMatchers = fflib_Match.getAndClearMatchers(1); System.Assert.areNotEqual(null, registeredMatchers); System.Assert.areEqual(1, registeredMatchers.size()); System.Assert.isInstanceOfType(registeredMatchers[0], fflib_MatcherDefinitions.Combined.class); } @isTest private static void eqRegistersCorrectMatcherType() { //Given/When Object x = fflib_Match.eq('hello'); //Then List registeredMatchers = fflib_Match.getAndClearMatchers(1); System.Assert.areNotEqual(null, registeredMatchers); System.Assert.areEqual(1, registeredMatchers.size()); System.Assert.isInstanceOfType(registeredMatchers[0], fflib_MatcherDefinitions.Eq.class); } @isTest public static void eqBooleanRegistersCorrectMatcherType() { //Given/When Object x = fflib_Match.eqBoolean(true); //Then List registeredMatchers = fflib_Match.getAndClearMatchers(1); System.Assert.areNotEqual(null, registeredMatchers); System.Assert.areEqual(1, registeredMatchers.size()); System.Assert.isInstanceOfType(registeredMatchers[0], fflib_MatcherDefinitions.Eq.class); } @isTest public static void eqDateRegistersCorrectMatcherType() { //Given/When Object x = fflib_Match.eqDate(Date.today()); //Then List registeredMatchers = fflib_Match.getAndClearMatchers(1); System.Assert.areNotEqual(null, registeredMatchers); System.Assert.areEqual(1, registeredMatchers.size()); System.Assert.isInstanceOfType(registeredMatchers[0], fflib_MatcherDefinitions.Eq.class); } @isTest public static void eqDatetimeRegistersCorrectMatcherType() { //Given/When Object x = fflib_Match.eqDatetime(System.now()); //Then List registeredMatchers = fflib_Match.getAndClearMatchers(1); System.Assert.areNotEqual(null, registeredMatchers); System.Assert.areEqual(1, registeredMatchers.size()); System.Assert.isInstanceOfType(registeredMatchers[0], fflib_MatcherDefinitions.Eq.class); } @isTest public static void eqDecimalRegistersCorrectMatcherType() { //Given/When Object x = fflib_Match.eqDecimal(123); //Then List registeredMatchers = fflib_Match.getAndClearMatchers(1); System.Assert.areNotEqual(null, registeredMatchers); System.Assert.areEqual(1, registeredMatchers.size()); System.Assert.isInstanceOfType(registeredMatchers[0], fflib_MatcherDefinitions.Eq.class); } @isTest public static void eqDoubleRegistersCorrectMatcherType() { //Given/When Object x = fflib_Match.eqDouble(123); //Then List registeredMatchers = fflib_Match.getAndClearMatchers(1); System.Assert.areNotEqual(null, registeredMatchers); System.Assert.areEqual(1, registeredMatchers.size()); System.Assert.isInstanceOfType(registeredMatchers[0], fflib_MatcherDefinitions.Eq.class); } @isTest public static void eqIdRegistersCorrectMatcherType() { //Given/When Object x = fflib_Match.eqId('001000000000001AAA'); //Then List registeredMatchers = fflib_Match.getAndClearMatchers(1); System.Assert.areNotEqual(null, registeredMatchers); System.Assert.areEqual(1, registeredMatchers.size()); System.Assert.isInstanceOfType(registeredMatchers[0], fflib_MatcherDefinitions.Eq.class); } @isTest public static void eqIntegerRegistersCorrectMatcherType() { //Given/When Object x = fflib_Match.eqInteger(123); //Then List registeredMatchers = fflib_Match.getAndClearMatchers(1); System.Assert.areNotEqual(null, registeredMatchers); System.Assert.areEqual(1, registeredMatchers.size()); System.Assert.isInstanceOfType(registeredMatchers[0], fflib_MatcherDefinitions.Eq.class); } @isTest public static void eqListRegistersCorrectMatcherType() { //Given/When Object x = fflib_Match.eqList(new List{ 'hello' }); //Then List registeredMatchers = fflib_Match.getAndClearMatchers(1); System.Assert.areNotEqual(null, registeredMatchers); System.Assert.areEqual(1, registeredMatchers.size()); System.Assert.isInstanceOfType(registeredMatchers[0], fflib_MatcherDefinitions.Eq.class); } @isTest public static void eqLongRegistersCorrectMatcherType() { //Given/When Object x = fflib_Match.eqLong(123); //Then List registeredMatchers = fflib_Match.getAndClearMatchers(1); System.Assert.areNotEqual(null, registeredMatchers); System.Assert.areEqual(1, registeredMatchers.size()); System.Assert.isInstanceOfType(registeredMatchers[0], fflib_MatcherDefinitions.Eq.class); } @isTest public static void eqSObjectFieldRegistersCorrectMatcherType() { //Given/When Schema.SObjectField f = Schema.getGlobalDescribe().get('Account').getDescribe().fields.getMap().get('Id'); Object x = fflib_Match.eqSObjectField(f); //Then List registeredMatchers = fflib_Match.getAndClearMatchers(1); System.Assert.areNotEqual(null, registeredMatchers); System.Assert.areEqual(1, registeredMatchers.size()); System.Assert.isInstanceOfType(registeredMatchers[0], fflib_MatcherDefinitions.Eq.class); } @isTest public static void eqSObjectTypeRegistersCorrectMatcherType() { //Given/When Schema.SObjectType ot = Schema.getGlobalDescribe().get('Account'); Object x = fflib_Match.eqSObjectType(ot); //Then List registeredMatchers = fflib_Match.getAndClearMatchers(1); System.Assert.areNotEqual(null, registeredMatchers); System.Assert.areEqual(1, registeredMatchers.size()); System.Assert.isInstanceOfType(registeredMatchers[0], fflib_MatcherDefinitions.Eq.class); } @isTest public static void eqStringRegistersCorrectMatcherType() { //Given/When Object x = fflib_Match.eqString('hello'); //Then List registeredMatchers = fflib_Match.getAndClearMatchers(1); System.Assert.areNotEqual(null, registeredMatchers); System.Assert.areEqual(1, registeredMatchers.size()); System.Assert.isInstanceOfType(registeredMatchers[0], fflib_MatcherDefinitions.Eq.class); } @isTest private static void refEqRegistersCorrectMatcherType() { //Given/When Object x = fflib_Match.refEq('hello'); //Then List registeredMatchers = fflib_Match.getAndClearMatchers(1); System.Assert.areNotEqual(null, registeredMatchers); System.Assert.areEqual(1, registeredMatchers.size()); System.Assert.isInstanceOfType(registeredMatchers[0], fflib_MatcherDefinitions.RefEq.class); } @isTest private static void anyBooleanRegistersCorrectMatcherType() { //Given/When Boolean x = fflib_Match.anyBoolean(); //Then List registeredMatchers = fflib_Match.getAndClearMatchers(1); System.Assert.areNotEqual(null, registeredMatchers); System.Assert.areEqual(1, registeredMatchers.size()); System.Assert.isInstanceOfType(registeredMatchers[0], fflib_MatcherDefinitions.AnyBoolean.class); } @isTest private static void anyDateRegistersCorrectMatcherType() { //Given/When Date x = fflib_Match.anyDate(); //Then List registeredMatchers = fflib_Match.getAndClearMatchers(1); System.Assert.areNotEqual(null, registeredMatchers); System.Assert.areEqual(1, registeredMatchers.size()); System.Assert.isInstanceOfType(registeredMatchers[0], fflib_MatcherDefinitions.AnyDate.class); } @isTest private static void anyDatetimeRegistersCorrectMatcherType() { //Given/When Datetime x = fflib_Match.anyDatetime(); //Then List registeredMatchers = fflib_Match.getAndClearMatchers(1); System.Assert.areNotEqual(null, registeredMatchers); System.Assert.areEqual(1, registeredMatchers.size()); System.Assert.isInstanceOfType(registeredMatchers[0], fflib_MatcherDefinitions.AnyDatetime.class); } @isTest private static void anyDecimalRegistersCorrectMatcherType() { //Given/When Decimal x = fflib_Match.anyDecimal(); //Then List registeredMatchers = fflib_Match.getAndClearMatchers(1); System.Assert.areNotEqual(null, registeredMatchers); System.Assert.areEqual(1, registeredMatchers.size()); System.Assert.isInstanceOfType(registeredMatchers[0], fflib_MatcherDefinitions.AnyDecimal.class); } @isTest private static void anyDoubleRegistersCorrectMatcherType() { //Given/When Double x = fflib_Match.anyDouble(); //Then List registeredMatchers = fflib_Match.getAndClearMatchers(1); System.Assert.areNotEqual(null, registeredMatchers); System.Assert.areEqual(1, registeredMatchers.size()); System.Assert.isInstanceOfType(registeredMatchers[0], fflib_MatcherDefinitions.AnyDouble.class); } @isTest private static void anyFieldSetRegistersCorrectMatcherType() { //Given/When Schema.FieldSet x = fflib_Match.anyFieldSet(); //Then List registeredMatchers = fflib_Match.getAndClearMatchers(1); System.Assert.areNotEqual(null, registeredMatchers); System.Assert.areEqual(1, registeredMatchers.size()); System.Assert.isInstanceOfType(registeredMatchers[0], fflib_MatcherDefinitions.AnyFieldSet.class); } @isTest private static void anyIdRegistersCorrectMatcherType() { //Given/When Id x = fflib_Match.anyId(); //Then List registeredMatchers = fflib_Match.getAndClearMatchers(1); System.Assert.areNotEqual(null, registeredMatchers); System.Assert.areEqual(1, registeredMatchers.size()); System.Assert.isInstanceOfType(registeredMatchers[0], fflib_MatcherDefinitions.AnyId.class); } @isTest private static void anyIntegerRegistersCorrectMatcherType() { //Given/When Integer x = fflib_Match.anyInteger(); //Then List registeredMatchers = fflib_Match.getAndClearMatchers(1); System.Assert.areNotEqual(null, registeredMatchers); System.Assert.areEqual(1, registeredMatchers.size()); System.Assert.isInstanceOfType(registeredMatchers[0], fflib_MatcherDefinitions.AnyInteger.class); } @isTest private static void anyListRegistersCorrectMatcherType() { //Given/When List x = fflib_Match.anyList(); //Then List registeredMatchers = fflib_Match.getAndClearMatchers(1); System.Assert.areNotEqual(null, registeredMatchers); System.Assert.areEqual(1, registeredMatchers.size()); System.Assert.isInstanceOfType(registeredMatchers[0], fflib_MatcherDefinitions.AnyList.class); } @isTest private static void anyLongRegistersCorrectMatcherType() { //Given/When Long x = fflib_Match.anyLong(); //Then List registeredMatchers = fflib_Match.getAndClearMatchers(1); System.Assert.areNotEqual(null, registeredMatchers); System.Assert.areEqual(1, registeredMatchers.size()); System.Assert.isInstanceOfType(registeredMatchers[0], fflib_MatcherDefinitions.AnyLong.class); } @isTest private static void anyObjectRegistersCorrectMatcherType() { //Given/When Object x = fflib_Match.anyObject(); //Then List registeredMatchers = fflib_Match.getAndClearMatchers(1); System.Assert.areNotEqual(null, registeredMatchers); System.Assert.areEqual(1, registeredMatchers.size()); System.Assert.isInstanceOfType(registeredMatchers[0], fflib_MatcherDefinitions.AnyObject.class); } @isTest private static void anyStringRegistersCorrectMatcherType() { //Given/When String x = fflib_Match.anyString(); //Then List registeredMatchers = fflib_Match.getAndClearMatchers(1); System.Assert.areNotEqual(null, registeredMatchers); System.Assert.areEqual(1, registeredMatchers.size()); System.Assert.isInstanceOfType(registeredMatchers[0], fflib_MatcherDefinitions.AnyString.class); } @isTest private static void anySObjectRegistersCorrectMatcherType() { //Given/When SObject x = fflib_Match.anySObject(); //Then List registeredMatchers = fflib_Match.getAndClearMatchers(1); System.Assert.areNotEqual(null, registeredMatchers); System.Assert.areEqual(1, registeredMatchers.size()); System.Assert.isInstanceOfType(registeredMatchers[0], fflib_MatcherDefinitions.AnySObject.class); } @isTest private static void anySObjectFieldRegistersCorrectMatcherType() { //Given/When SObjectField x = fflib_Match.anySObjectField(); //Then List registeredMatchers = fflib_Match.getAndClearMatchers(1); System.Assert.areNotEqual(null, registeredMatchers); System.Assert.areEqual(1, registeredMatchers.size()); System.Assert.isInstanceOfType(registeredMatchers[0], fflib_MatcherDefinitions.AnySObjectField.class); } @isTest private static void anySObjectTypeRegistersCorrectMatcherType() { //Given/When SObjectType x = fflib_Match.anySObjectType(); //Then List registeredMatchers = fflib_Match.getAndClearMatchers(1); System.Assert.areNotEqual(null, registeredMatchers); System.Assert.areEqual(1, registeredMatchers.size()); System.Assert.isInstanceOfType(registeredMatchers[0], fflib_MatcherDefinitions.AnySObjectType.class); } @isTest private static void dateAfterRegistersCorrectMatcherType() { //Given/When Date x = fflib_Match.dateAfter(Date.today()); //Then List registeredMatchers = fflib_Match.getAndClearMatchers(1); System.Assert.areNotEqual(null, registeredMatchers); System.Assert.areEqual(1, registeredMatchers.size()); System.Assert.isInstanceOfType(registeredMatchers[0], fflib_MatcherDefinitions.DatetimeAfter.class); } @isTest private static void dateBeforeRegistersCorrectMatcherType() { //Given/When Date x = fflib_Match.dateBefore(Date.today()); //Then List registeredMatchers = fflib_Match.getAndClearMatchers(1); System.Assert.areNotEqual(null, registeredMatchers); System.Assert.areEqual(1, registeredMatchers.size()); System.Assert.isInstanceOfType(registeredMatchers[0], fflib_MatcherDefinitions.DatetimeBefore.class); } @isTest private static void dateBetweenRegistersCorrectMatcherType() { //Given/When Date x = fflib_Match.dateBetween(Date.today(), Date.today()); //Then List registeredMatchers = fflib_Match.getAndClearMatchers(1); System.Assert.areNotEqual(null, registeredMatchers); System.Assert.areEqual(1, registeredMatchers.size()); System.Assert.isInstanceOfType(registeredMatchers[0], fflib_MatcherDefinitions.DatetimeBetween.class); } @isTest private static void datetimeAfterRegistersCorrectMatcherType() { //Given/When Datetime x = fflib_Match.datetimeAfter(System.now()); //Then List registeredMatchers = fflib_Match.getAndClearMatchers(1); System.Assert.areNotEqual(null, registeredMatchers); System.Assert.areEqual(1, registeredMatchers.size()); System.Assert.isInstanceOfType(registeredMatchers[0], fflib_MatcherDefinitions.DatetimeAfter.class); } @isTest private static void datetimeBeforeRegistersCorrectMatcherType() { //Given/When Datetime x = fflib_Match.datetimeBefore(System.now()); //Then List registeredMatchers = fflib_Match.getAndClearMatchers(1); System.Assert.areNotEqual(null, registeredMatchers); System.Assert.areEqual(1, registeredMatchers.size()); System.Assert.isInstanceOfType(registeredMatchers[0], fflib_MatcherDefinitions.DatetimeBefore.class); } @isTest private static void datetimeBetweenRegistersCorrectMatcherType() { //Given/When Datetime x = fflib_Match.datetimeBetween(System.now(), System.now()); //Then List registeredMatchers = fflib_Match.getAndClearMatchers(1); System.Assert.areNotEqual(null, registeredMatchers); System.Assert.areEqual(1, registeredMatchers.size()); System.Assert.isInstanceOfType(registeredMatchers[0], fflib_MatcherDefinitions.DatetimeBetween.class); } @isTest private static void decimalBetweenRegistersCorrectMatcherType() { //Given/When Decimal x = fflib_Match.decimalBetween(0, 10); //Then List registeredMatchers = fflib_Match.getAndClearMatchers(1); System.Assert.areNotEqual(null, registeredMatchers); System.Assert.areEqual(1, registeredMatchers.size()); System.Assert.isInstanceOfType(registeredMatchers[0], fflib_MatcherDefinitions.DecimalBetween.class); } @isTest private static void decimalLessThanRegistersCorrectMatcherType() { //Given/When Decimal x = fflib_Match.decimalLessThan(0); //Then List registeredMatchers = fflib_Match.getAndClearMatchers(1); System.Assert.areNotEqual(null, registeredMatchers); System.Assert.areEqual(1, registeredMatchers.size()); System.Assert.isInstanceOfType(registeredMatchers[0], fflib_MatcherDefinitions.DecimalLessThan.class); } @isTest private static void decimalMoreThanRegistersCorrectMatcherType() { //Given/When Decimal x = fflib_Match.decimalMoreThan(0); //Then List registeredMatchers = fflib_Match.getAndClearMatchers(1); System.Assert.areNotEqual(null, registeredMatchers); System.Assert.areEqual(1, registeredMatchers.size()); System.Assert.isInstanceOfType(registeredMatchers[0], fflib_MatcherDefinitions.DecimalMoreThan.class); } @isTest private static void doubleBetweenRegistersCorrectMatcherType() { //Given/When Double x = fflib_Match.doubleBetween(0, 10); //Then List registeredMatchers = fflib_Match.getAndClearMatchers(1); System.Assert.areNotEqual(null, registeredMatchers); System.Assert.areEqual(1, registeredMatchers.size()); System.Assert.isInstanceOfType(registeredMatchers[0], fflib_MatcherDefinitions.DecimalBetween.class); } @isTest private static void doubleLessThanRegistersCorrectMatcherType() { //Given/When Double x = fflib_Match.doubleLessThan(0); //Then List registeredMatchers = fflib_Match.getAndClearMatchers(1); System.Assert.areNotEqual(null, registeredMatchers); System.Assert.areEqual(1, registeredMatchers.size()); System.Assert.isInstanceOfType(registeredMatchers[0], fflib_MatcherDefinitions.DecimalLessThan.class); } @isTest private static void doubleMoreThanRegistersCorrectMatcherType() { //Given/When Double x = fflib_Match.doubleMoreThan(0); //Then List registeredMatchers = fflib_Match.getAndClearMatchers(1); System.Assert.areNotEqual(null, registeredMatchers); System.Assert.areEqual(1, registeredMatchers.size()); System.Assert.isInstanceOfType(registeredMatchers[0], fflib_MatcherDefinitions.DecimalMoreThan.class); } @isTest private static void fieldSetEquivalentWithNullFieldSetThrowsException() { try { fflib_Match.fieldSetEquivalentTo(null); System.Assert.fail('ExpectedException'); } catch (fflib_ApexMocks.ApexMocksException e) { System.Assert.areEqual('Arg cannot be null: null', e.getMessage()); } } @isTest private static void fieldSetEquivalentToRegistersCorrectMatcherType() { Schema.FieldSet anyFieldSet = fflib_ApexMocksUtilsTest.findAnyFieldSet(); if (anyFieldSet == null) { return; } //Given/When Schema.FieldSet x = fflib_Match.fieldSetEquivalentTo(anyFieldSet); //Then List registeredMatchers = fflib_Match.getAndClearMatchers(1); System.Assert.areNotEqual(null, registeredMatchers); System.Assert.areEqual(1, registeredMatchers.size()); System.Assert.isInstanceOfType(registeredMatchers[0], fflib_MatcherDefinitions.FieldSetEquivalentTo.class); } @isTest private static void integerBetweenRegistersCorrectMatcherType() { //Given/When Integer x = fflib_Match.integerBetween(0, 10); //Then List registeredMatchers = fflib_Match.getAndClearMatchers(1); System.Assert.areNotEqual(null, registeredMatchers); System.Assert.areEqual(1, registeredMatchers.size()); System.Assert.isInstanceOfType(registeredMatchers[0], fflib_MatcherDefinitions.DecimalBetween.class); } @isTest private static void integerLessThanRegistersCorrectMatcherType() { //Given/When Integer x = fflib_Match.integerLessThan(0); //Then List registeredMatchers = fflib_Match.getAndClearMatchers(1); System.Assert.areNotEqual(null, registeredMatchers); System.Assert.areEqual(1, registeredMatchers.size()); System.Assert.isInstanceOfType(registeredMatchers[0], fflib_MatcherDefinitions.DecimalLessThan.class); } @isTest private static void integerMoreThanRegistersCorrectMatcherType() { //Given/When Integer x = fflib_Match.integerMoreThan(0); //Then List registeredMatchers = fflib_Match.getAndClearMatchers(1); System.Assert.areNotEqual(null, registeredMatchers); System.Assert.areEqual(1, registeredMatchers.size()); System.Assert.isInstanceOfType(registeredMatchers[0], fflib_MatcherDefinitions.DecimalMoreThan.class); } @isTest private static void isNotNullRegistersCorrectMatcherType() { //Given/When Object x = fflib_Match.isNotNull(); //Then List registeredMatchers = fflib_Match.getAndClearMatchers(1); System.Assert.areNotEqual(null, registeredMatchers); System.Assert.areEqual(1, registeredMatchers.size()); System.Assert.isInstanceOfType(registeredMatchers[0], fflib_MatcherDefinitions.IsNotNull.class); } @isTest private static void isNullRegistersCorrectMatcherType() { //Given/When Object x = fflib_Match.isNull(); //Then List registeredMatchers = fflib_Match.getAndClearMatchers(1); System.Assert.areNotEqual(null, registeredMatchers); System.Assert.areEqual(1, registeredMatchers.size()); System.Assert.isInstanceOfType(registeredMatchers[0], fflib_MatcherDefinitions.IsNull.class); } @isTest private static void listContainsRegistersCorrectMatcherType() { //Given/When Object x = fflib_Match.listContains('fred'); //Then List registeredMatchers = fflib_Match.getAndClearMatchers(1); System.Assert.areNotEqual(null, registeredMatchers); System.Assert.areEqual(1, registeredMatchers.size()); System.Assert.isInstanceOfType(registeredMatchers[0], fflib_MatcherDefinitions.ListContains.class); } @isTest private static void listIsEmptyRegistersCorrectMatcherType() { //Given/When Object x = fflib_Match.listIsEmpty(); //Then List registeredMatchers = fflib_Match.getAndClearMatchers(1); System.Assert.areNotEqual(null, registeredMatchers); System.Assert.areEqual(1, registeredMatchers.size()); System.Assert.isInstanceOfType(registeredMatchers[0], fflib_MatcherDefinitions.ListIsEmpty.class); } @isTest private static void longBetweenRegistersCorrectMatcherType() { //Given/When Long x = fflib_Match.longBetween(0, 10); //Then List registeredMatchers = fflib_Match.getAndClearMatchers(1); System.Assert.areNotEqual(null, registeredMatchers); System.Assert.areEqual(1, registeredMatchers.size()); System.Assert.isInstanceOfType(registeredMatchers[0], fflib_MatcherDefinitions.DecimalBetween.class); } @isTest private static void longLessThanRegistersCorrectMatcherType() { //Given/When Long x = fflib_Match.longLessThan(0); //Then List registeredMatchers = fflib_Match.getAndClearMatchers(1); System.Assert.areNotEqual(null, registeredMatchers); System.Assert.areEqual(1, registeredMatchers.size()); System.Assert.isInstanceOfType(registeredMatchers[0], fflib_MatcherDefinitions.DecimalLessThan.class); } @isTest private static void longMoreThanRegistersCorrectMatcherType() { //Given/When Long x = fflib_Match.longMoreThan(0); //Then List registeredMatchers = fflib_Match.getAndClearMatchers(1); System.Assert.areNotEqual(null, registeredMatchers); System.Assert.areEqual(1, registeredMatchers.size()); System.Assert.isInstanceOfType(registeredMatchers[0], fflib_MatcherDefinitions.DecimalMoreThan.class); } @isTest private static void sObjectOfTypeRegistersCorrectMatcherType() { //Given Schema.SObjectType ot = Schema.getGlobalDescribe().get('Account'); if (ot == null) { return; } //When SObject x = fflib_Match.sObjectOfType(ot); //Then List registeredMatchers = fflib_Match.getAndClearMatchers(1); System.Assert.areNotEqual(null, registeredMatchers); System.Assert.areEqual(1, registeredMatchers.size()); System.Assert.isInstanceOfType(registeredMatchers[0], fflib_MatcherDefinitions.SObjectOfType.class); } @isTest private static void sObjectWithRegistersCorrectMatcherType() { //Given Schema.SObjectType ot = Schema.getGlobalDescribe().get('Account'); if (ot == null) { return; } Schema.SObjectField f = ot.getDescribe().fields.getMap().get('Id'); //When SObject x = fflib_Match.sObjectWith(new Map{ f=>null }); //Then List registeredMatchers = fflib_Match.getAndClearMatchers(1); System.Assert.areNotEqual(null, registeredMatchers); System.Assert.areEqual(1, registeredMatchers.size()); System.Assert.isInstanceOfType(registeredMatchers[0], fflib_MatcherDefinitions.SObjectWith.class); } @isTest private static void sObjectsWithRegistersCorrectMatcherType() { //Given Schema.SObjectType ot = Schema.getGlobalDescribe().get('Account'); if (ot == null) { return; } Schema.SObjectField f = ot.getDescribe().fields.getMap().get('Id'); //When SObject[] x = fflib_Match.sObjectsWith(new list>{ new map {f=>null} }); //Then List registeredMatchers = fflib_Match.getAndClearMatchers(1); System.Assert.areNotEqual(null, registeredMatchers); System.Assert.areEqual(1, registeredMatchers.size()); System.Assert.isInstanceOfType(registeredMatchers[0], fflib_MatcherDefinitions.SObjectsWith.class); } @isTest private static void sObjectsWithMatchInOrderRegistersCorrectMatcherType() { //Given Schema.SObjectType ot = Schema.getGlobalDescribe().get('Account'); if (ot == null) { return; } Schema.SObjectField f = ot.getDescribe().fields.getMap().get('Id'); //When SObject[] x = fflib_Match.sObjectsWith(new list>{ new map {f=>null} }, false); //Then List registeredMatchers = fflib_Match.getAndClearMatchers(1); System.Assert.areNotEqual(null, registeredMatchers); System.Assert.areEqual(1, registeredMatchers.size()); System.Assert.isInstanceOfType(registeredMatchers[0], fflib_MatcherDefinitions.SObjectsWith.class, String.valueOf(registeredMatchers)); } @isTest private static void sObjectWithIdRegistersCorrectMatcherType() { //Given/When SObject x = fflib_Match.sObjectWithId('001000000000001AAA'); //Then List registeredMatchers = fflib_Match.getAndClearMatchers(1); System.Assert.areNotEqual(null, registeredMatchers); System.Assert.areEqual(1, registeredMatchers.size()); System.Assert.isInstanceOfType(registeredMatchers[0], fflib_MatcherDefinitions.SObjectWithId.class); } @isTest private static void sObjectWithNameRegistersCorrectMatcherType() { //Given/When SObject x = fflib_Match.sObjectWithName('hello'); //Then List registeredMatchers = fflib_Match.getAndClearMatchers(1); System.Assert.areNotEqual(null, registeredMatchers); System.Assert.areEqual(1, registeredMatchers.size()); System.Assert.isInstanceOfType(registeredMatchers[0], fflib_MatcherDefinitions.SObjectWithName.class); } @isTest private static void stringContainsRegistersCorrectMatcherType() { //Given/When String x = fflib_Match.stringContains('hello'); //Then List registeredMatchers = fflib_Match.getAndClearMatchers(1); System.Assert.areNotEqual(null, registeredMatchers); System.Assert.areEqual(1, registeredMatchers.size()); System.Assert.isInstanceOfType(registeredMatchers[0], fflib_MatcherDefinitions.StringContains.class); } @isTest private static void stringEndsWithRegistersCorrectMatcherType() { //Given/When String x = fflib_Match.stringEndsWith('hello'); //Then List registeredMatchers = fflib_Match.getAndClearMatchers(1); System.Assert.areNotEqual(null, registeredMatchers); System.Assert.areEqual(1, registeredMatchers.size()); System.Assert.isInstanceOfType(registeredMatchers[0], fflib_MatcherDefinitions.StringEndsWith.class); } @isTest private static void stringIsBlankRegistersCorrectMatcherType() { //Given/When String x = fflib_Match.stringIsBlank(); //Then List registeredMatchers = fflib_Match.getAndClearMatchers(1); System.Assert.areNotEqual(null, registeredMatchers); System.Assert.areEqual(1, registeredMatchers.size()); System.Assert.isInstanceOfType(registeredMatchers[0], fflib_MatcherDefinitions.StringIsBlank.class); } @isTest private static void stringIsNotBlankRegistersCorrectMatcherType() { //Given/When String x = fflib_Match.stringIsNotBlank(); //Then List registeredMatchers = fflib_Match.getAndClearMatchers(1); System.Assert.areNotEqual(null, registeredMatchers); System.Assert.areEqual(1, registeredMatchers.size()); System.Assert.isInstanceOfType(registeredMatchers[0], fflib_MatcherDefinitions.StringIsNotBlank.class); } @isTest private static void stringMatchesRegistersCorrectMatcherType() { //Given/When String x = fflib_Match.stringMatches('[a-z]*'); //Then List registeredMatchers = fflib_Match.getAndClearMatchers(1); System.Assert.areNotEqual(null, registeredMatchers); System.Assert.areEqual(1, registeredMatchers.size()); System.Assert.isInstanceOfType(registeredMatchers[0], fflib_MatcherDefinitions.StringMatches.class); } @isTest private static void stringStartsWithRegistersCorrectMatcherType() { //Given/When String x = fflib_Match.stringStartsWith('hello'); //Then List registeredMatchers = fflib_Match.getAndClearMatchers(1); System.Assert.areNotEqual(null, registeredMatchers); System.Assert.areEqual(1, registeredMatchers.size()); System.Assert.isInstanceOfType(registeredMatchers[0], fflib_MatcherDefinitions.StringStartsWith.class); } private class AlwaysMatch implements fflib_IMatcher { public Boolean matches(Object arg) { return true; } } private class NeverMatch implements fflib_IMatcher { public Boolean matches(Object arg) { return false; } } } ================================================ FILE: sfdx-source/apex-mocks/test/classes/fflib_MatchTest.cls-meta.xml ================================================ 63.0 ================================================ FILE: sfdx-source/apex-mocks/test/classes/fflib_MatcherDefinitionsTest.cls ================================================ /** * Copyright (c) 2014-2016, FinancialForce.com, inc * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * - Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * - Neither the name of the FinancialForce.com, inc nor the names of its contributors * may be used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ @isTest public class fflib_MatcherDefinitionsTest { private static final List INTERNAL_MATCHERS = new List{ new fflib_MatcherDefinitions.StringContains('bob'), new fflib_MatcherDefinitions.StringContains('tom'), new fflib_MatcherDefinitions.StringContains('fred') }; private static final Date TODAY = System.today(); private static final Datetime NOW = System.now(); private static final SObject ACCOUNT_RECORD; private static final Schema.SObjectType ACCOUNT_OBJECT_TYPE; private static final Schema.SObjectType OPPORTUNITY_OBJECT_TYPE; private static final Schema.SobjectType GROUP_OBJECT_TYPE; private static final Sobject[] GROUP_RECORDS; static { Map globalDescribe = Schema.getGlobalDescribe(); ACCOUNT_OBJECT_TYPE = globalDescribe.get('Account'); OPPORTUNITY_OBJECT_TYPE = globalDescribe.get('Opportunity'); GROUP_OBJECT_TYPE = globalDescribe.get('Group'); SObject accountRecord = ACCOUNT_OBJECT_TYPE.newSObject(); accountRecord.put('Name', 'MatcherDefinitionTestAccount' + System.now()); accountRecord.Id = fflib_IDGenerator.generate(Account.SObjectType); ACCOUNT_RECORD = accountRecord; GROUP_RECORDS = new list { new Group(Name = 'MatcherDefnTestGroup0'+System.now(), DeveloperName='MatcherDefnTestGroup0'+System.now().getTime(),Type='Queue'), new Group(Name = 'MatcherDefnTestGroup1'+System.now(), DeveloperName='MatcherDefnTestGroup1'+System.now().getTime(),Type='Queue') }; insert GROUP_RECORDS; } @isTest private static void whenConstructingCombinedWithNullConnectiveExpressionShouldThrowException() { try { fflib_IMatcher matcher = new fflib_MatcherDefinitions.Combined(null, INTERNAL_MATCHERS); System.Assert.fail('Expecting exception'); } catch (fflib_ApexMocks.ApexMocksException e) { System.Assert.areEqual('Invalid connective expression: null', e.getMessage()); } } @isTest private static void whenConstructingCombinedWithNullInternalMatchersShouldThrowException() { try { fflib_IMatcher matcher = new fflib_MatcherDefinitions.Combined(fflib_MatcherDefinitions.Connective.ALL, null); System.Assert.fail('Expecting exception'); } catch (fflib_ApexMocks.ApexMocksException e) { System.Assert.areEqual('Invalid inner matchers: null', e.getMessage()); } } @isTest private static void whenConstructingCombinedWithEmptyInternalMatchersShouldThrowException() { try { fflib_IMatcher matcher = new fflib_MatcherDefinitions.Combined(fflib_MatcherDefinitions.Connective.ALL, new List()); System.Assert.fail('Expecting exception'); } catch (fflib_ApexMocks.ApexMocksException e) { System.Assert.areEqual('Invalid inner matchers: ()', e.getMessage()); } } @isTest private static void whenCombinedMatchesWithAllExpressionShouldReturnCorrectResults() { fflib_IMatcher matcher = new fflib_MatcherDefinitions.Combined(fflib_MatcherDefinitions.Connective.ALL, INTERNAL_MATCHERS); System.Assert.isFalse(matcher.matches(null)); System.Assert.isFalse(matcher.matches('ted')); System.Assert.isFalse(matcher.matches('bob')); System.Assert.isFalse(matcher.matches('tomfred')); System.Assert.isTrue(matcher.matches('bobtomfred')); } @isTest private static void whenCombinedMatchesWithAtLeastOneExpressionShouldReturnCorrectResults() { fflib_IMatcher matcher = new fflib_MatcherDefinitions.Combined(fflib_MatcherDefinitions.Connective.AT_LEAST_ONE, INTERNAL_MATCHERS); System.Assert.isFalse(matcher.matches(null)); System.Assert.isFalse(matcher.matches('ted')); System.Assert.isTrue(matcher.matches('bob')); System.Assert.isTrue(matcher.matches('tomfred')); System.Assert.isTrue(matcher.matches('bobtomfred')); } @isTest private static void whenCombinedMatchesWithNoneExpressionShouldReturnCorrectResults() { fflib_IMatcher matcher = new fflib_MatcherDefinitions.Combined(fflib_MatcherDefinitions.Connective.NONE, INTERNAL_MATCHERS); System.Assert.isTrue(matcher.matches(null)); System.Assert.isTrue(matcher.matches('ted')); System.Assert.isFalse(matcher.matches('bob')); System.Assert.isFalse(matcher.matches('tomfred')); System.Assert.isFalse(matcher.matches('bobtomfred')); } @isTest private static void whenCombinedMatcherToStringReturnsExpectedString() { List innerMatchers = new List{ new StringMatcher('one'), new StringMatcher('two'), new StringMatcher('three') }; System.Assert.areEqual( '[any of: "one", "two", "three"]', '' + new fflib_MatcherDefinitions.Combined(fflib_MatcherDefinitions.Connective.AT_LEAST_ONE, innerMatchers) ); System.Assert.areEqual( '[all of: "one", "two", "three"]', '' + new fflib_MatcherDefinitions.Combined(fflib_MatcherDefinitions.Connective.ALL, innerMatchers) ); System.Assert.areEqual( '[none of: "one", "two", "three"]', '' + new fflib_MatcherDefinitions.Combined(fflib_MatcherDefinitions.Connective.NONE, innerMatchers) ); } @isTest private static void constructEq_WithNullArg_ThrowsException() { try { new fflib_MatcherDefinitions.Eq(null); System.Assert.fail('Expected exception'); } catch (fflib_ApexMocks.ApexMocksException e) { System.Assert.areEqual('Arg cannot be null: null', e.getMessage()); } } @isTest private static void whenEqMatchesShouldReturnCorrectResults() { List s1 = new List {'bob', 'tom'}; List s2 = new List {'bob', 'tom'}; fflib_IMatcher matcher = new fflib_MatcherDefinitions.Eq(s1); System.Assert.isFalse(matcher.matches(null)); System.Assert.isFalse(matcher.matches(new List {'bob'})); System.Assert.isTrue(matcher.matches(s2)); System.Assert.isTrue(matcher.matches(s1)); } @isTest private static void whenEqToStringShouldReturnExpectedString() { System.Assert.areEqual('[equals 1]', '' + new fflib_MatcherDefinitions.Eq(1)); } @isTest private static void constructRefEq_WithNullArg_ThrowsException() { try { new fflib_MatcherDefinitions.RefEq(null); System.Assert.fail('Expected exception'); } catch (fflib_ApexMocks.ApexMocksException e) { System.Assert.areEqual('Arg cannot be null: null', e.getMessage()); } } @isTest private static void whenRefEqMatchesShouldReturnCorrectResults() { List s1 = new List {'bob', 'tom'}; List s2 = new List {'bob', 'tom'}; fflib_IMatcher matcher = new fflib_MatcherDefinitions.RefEq(s1); System.Assert.isFalse(matcher.matches(null)); System.Assert.isFalse(matcher.matches(s2)); System.Assert.isTrue(matcher.matches(s1)); } @isTest private static void whenRefEqToStringReturnsExpectedString() { List s1 = new List {'bob', 'tom'}; System.Assert.areEqual('[reference equals ' + JSON.serialize(s1, false) + ']', '' + new fflib_MatcherDefinitions.RefEq(s1)); } @isTest private static void whenAnyBooleanMatchesShouldReturnCorrectResults() { fflib_IMatcher matcher = new fflib_MatcherDefinitions.AnyBoolean(); System.Assert.isFalse(matcher.matches(null)); System.Assert.isFalse(matcher.matches(9)); System.Assert.isTrue(matcher.matches(true)); System.Assert.isTrue(matcher.matches(false)); } @isTest private static void whenAnyBooleanToStringReturnsExpectedString() { System.Assert.areEqual('[any Boolean]', '' + new fflib_MatcherDefinitions.AnyBoolean()); } @isTest private static void whenAnyDateMatchesShouldReturnCorrectResults() { fflib_IMatcher matcher = new fflib_MatcherDefinitions.AnyDate(); System.Assert.isFalse(matcher.matches(null)); System.Assert.isFalse(matcher.matches(NOW)); System.Assert.isTrue(matcher.matches(TODAY)); } @isTest private static void whenAnyDateToStringReturnsExpectedString() { System.Assert.areEqual('[any Date]', '' + new fflib_MatcherDefinitions.AnyDate()); } @isTest private static void whenAnyDatetimeMatchesShouldReturnCorrectResults() { fflib_IMatcher matcher = new fflib_MatcherDefinitions.AnyDatetime(); System.Assert.isFalse(matcher.matches(null)); System.Assert.isTrue(matcher.matches(NOW)); System.Assert.isTrue(matcher.matches(TODAY)); } @isTest private static void whenAnyDatetimeToStringReturnsExpectedString() { System.Assert.areEqual('[any DateTime]', '' + new fflib_MatcherDefinitions.AnyDatetime()); } @isTest private static void whenAnyDecimalMatchesShouldReturnCorrectResults() { fflib_IMatcher matcher = new fflib_MatcherDefinitions.AnyDecimal(); System.Assert.isFalse(matcher.matches(null)); System.Assert.isFalse(matcher.matches('bob')); System.Assert.isTrue(matcher.matches(9)); System.Assert.isTrue(matcher.matches(9L)); System.Assert.isTrue(matcher.matches(9.99)); } @isTest private static void whenAnyDecimalToStringReturnsExpectedString() { System.Assert.areEqual('[any Decimal]', '' + new fflib_MatcherDefinitions.AnyDecimal()); } @isTest private static void whenAnyDoubleMatchesShouldReturnCorrectResults() { fflib_IMatcher matcher = new fflib_MatcherDefinitions.AnyDouble(); System.Assert.isFalse(matcher.matches(null)); System.Assert.isFalse(matcher.matches('bob')); System.Assert.isTrue(matcher.matches(9)); System.Assert.isTrue(matcher.matches(9L)); System.Assert.isTrue(matcher.matches(9.99)); } @isTest private static void whenAnyDoubleToStringReturnsExpectedString() { System.Assert.areEqual('[any Double]', '' + new fflib_MatcherDefinitions.AnyDouble()); } @isTest private static void whenAnyFieldSetMatchesShouldReturnCorrectResults() { fflib_IMatcher matcher = new fflib_MatcherDefinitions.AnyFieldSet(); System.Assert.isFalse(matcher.matches(null)); System.Assert.isFalse(matcher.matches('bob')); Schema.FieldSet anyFieldSet = fflib_ApexMocksUtilsTest.findAnyFieldSet(); if (anyFieldSet != null) { System.Assert.isTrue(matcher.matches(anyFieldSet)); } } @isTest private static void whenAnyFieldSetToStringReturnsExpectedString() { System.Assert.areEqual('[any FieldSet]', '' + new fflib_MatcherDefinitions.AnyFieldSet()); } @isTest private static void whenAnyIdMatchesShouldReturnCorrectResults() { String idString = fflib_IDGenerator.generate(Account.SObjectType); Id accountId = fflib_IDGenerator.generate(Account.SObjectType); fflib_IMatcher matcher = new fflib_MatcherDefinitions.AnyId(); System.Assert.isFalse(matcher.matches(null)); System.Assert.isFalse(matcher.matches('bob')); System.Assert.isTrue(matcher.matches(idString)); System.Assert.isTrue(matcher.matches(accountId)); } @isTest private static void whenAnyIdToStringReturnsExpectedString() { System.Assert.areEqual('[any Id]', '' + new fflib_MatcherDefinitions.AnyId()); } @isTest private static void whenAnyIntegerMatchesShouldReturnCorrectResults() { fflib_IMatcher matcher = new fflib_MatcherDefinitions.AnyInteger(); System.Assert.isFalse(matcher.matches(null)); System.Assert.isFalse(matcher.matches('bob')); System.Assert.isFalse(matcher.matches(9L)); System.Assert.isFalse(matcher.matches(9.99)); System.Assert.isTrue(matcher.matches(9)); } @isTest private static void whenAnyIntegerToStringReturnsExpectedString() { System.Assert.areEqual('[any Integer]', '' + new fflib_MatcherDefinitions.AnyInteger()); } @isTest private static void whenAnyListMatchesShouldReturnCorrectResults() { fflib_IMatcher matcher = new fflib_MatcherDefinitions.AnyList(); System.Assert.isFalse(matcher.matches(null)); System.Assert.isFalse(matcher.matches('bob')); System.Assert.isTrue(matcher.matches(new List())); System.Assert.isTrue(matcher.matches(new List())); System.Assert.isTrue(matcher.matches(new List())); } @isTest private static void whenAnyListToStringReturnsExpectedString() { System.Assert.areEqual('[any list]', '' + new fflib_MatcherDefinitions.AnyList()); } @isTest private static void whenAnyLongMatchesShouldReturnCorrectResults() { fflib_IMatcher matcher = new fflib_MatcherDefinitions.AnyLong(); System.Assert.isFalse(matcher.matches(null)); System.Assert.isFalse(matcher.matches('bob')); System.Assert.isFalse(matcher.matches(9.99)); System.Assert.isTrue(matcher.matches(9)); System.Assert.isTrue(matcher.matches(9L)); } @isTest private static void whenAnyLongToStringReturnsExpectedString() { System.Assert.areEqual('[any Long]', '' + new fflib_MatcherDefinitions.AnyLong()); } @isTest private static void whenAnyObjectMatchesShouldReturnCorrectResults() { fflib_IMatcher matcher = new fflib_MatcherDefinitions.AnyObject(); System.Assert.isFalse(matcher.matches(null)); System.Assert.isTrue(matcher.matches('bob')); System.Assert.isTrue(matcher.matches(9)); System.Assert.isTrue(matcher.matches(new List())); } @isTest private static void whenAnyObjectToStringReturnsExpectedString() { System.Assert.areEqual('[any Object]', '' + new fflib_MatcherDefinitions.AnyObject()); } @isTest private static void whenAnyStringMatchesShouldReturnCorrectResults() { fflib_IMatcher matcher = new fflib_MatcherDefinitions.AnyString(); System.Assert.isFalse(matcher.matches(null)); System.Assert.isFalse(matcher.matches(9)); System.Assert.isTrue(matcher.matches('bob')); } @isTest private static void whenAnyStringToStringReturnsExpectedString() { System.Assert.areEqual('[any String]', '' + new fflib_MatcherDefinitions.AnyString()); } @isTest private static void whenAnySObjectMatchesShouldReturnCorrectResults() { fflib_IMatcher matcher = new fflib_MatcherDefinitions.AnySObject(); System.Assert.isFalse(matcher.matches(null)); System.Assert.isFalse(matcher.matches('bob')); System.Assert.isTrue(matcher.matches(new Account())); } @isTest private static void whenAnySObjectToStringReturnsExpectedString() { System.Assert.areEqual('[any SObject]', '' + new fflib_MatcherDefinitions.AnySObject()); } @isTest private static void whenAnySObjectFieldMatchesShouldReturnCorrectResults() { fflib_IMatcher matcher = new fflib_MatcherDefinitions.AnySObjectField(); System.Assert.isFalse(matcher.matches(null)); System.Assert.isFalse(matcher.matches(new Account())); System.Assert.isTrue(matcher.matches(Account.Id)); } @isTest private static void whenAnySObjectFieldToStringReturnsExpectedString() { System.Assert.areEqual('[any SObjectField]', '' + new fflib_MatcherDefinitions.AnySObjectField()); } @isTest private static void whenAnySObjectTypeMatchesShouldReturnCorrectResults() { fflib_IMatcher matcher = new fflib_MatcherDefinitions.AnySObjectType(); System.Assert.isFalse(matcher.matches(null)); System.Assert.isFalse(matcher.matches(new Account())); System.Assert.isTrue(matcher.matches(Account.SObjectType)); } @isTest private static void whenAnySObjectTypeToStringReturnsExpectedString() { System.Assert.areEqual('[any SObjectType]', '' + new fflib_MatcherDefinitions.AnySObjectType()); } @isTest private static void constructDatetimeAfter_WithNullFromDatetime_ThrowsException() { try { new fflib_MatcherDefinitions.DatetimeAfter(null, true); System.Assert.fail('Expected exception'); } catch (fflib_ApexMocks.ApexMocksException e) { System.Assert.areEqual('Arg cannot be null: null', e.getMessage()); } } @isTest private static void constructDatetimeAfter_WithNullInclusive_ThrowsException() { try { new fflib_MatcherDefinitions.DatetimeAfter(System.now(), null); System.Assert.fail('Expected exception'); } catch (fflib_ApexMocks.ApexMocksException e) { System.Assert.areEqual('Arg cannot be null: null', e.getMessage()); } } @isTest private static void whenDatetimeAfterMatchesWithoutInclusiveShouldReturnCorrectResults() { fflib_IMatcher matcher = new fflib_MatcherDefinitions.DatetimeAfter(NOW, false); System.Assert.isFalse(matcher.matches(null)); System.Assert.isFalse(matcher.matches('bob')); System.Assert.isFalse(matcher.matches(NOW.addSeconds(-1))); System.Assert.isFalse(matcher.matches(NOW)); System.Assert.isTrue(matcher.matches(NOW.addSeconds(1))); } @isTest private static void whenDatetimeAfterMatchesWithInclusiveShouldReturnCorrectResults() { fflib_IMatcher matcher = new fflib_MatcherDefinitions.DatetimeAfter(NOW, true); System.Assert.isFalse(matcher.matches(null)); System.Assert.isFalse(matcher.matches('bob')); System.Assert.isFalse(matcher.matches(NOW.addSeconds(-1))); System.Assert.isTrue(matcher.matches(NOW)); System.Assert.isTrue(matcher.matches(NOW.addSeconds(1))); } @isTest private static void whenDatetimeAfterWithInclusiveToStringReturnsExpectedString() { // Given DateTime fromDate = DateTime.newInstanceGmt(2019, 1, 1, 12, 0, 0); fflib_IMatcher matcher = new fflib_MatcherDefinitions.DatetimeAfter(fromDate, true); // When String actual = '' + matcher; // Then System.Assert.areEqual('[on or after "2019-01-01T12:00:00.000Z"]', actual); } @isTest private static void whenDatetimeAfterWithNotInclusiveToStringReturnsExpectedString() { // Given DateTime fromDate = DateTime.newInstanceGmt(2019, 1, 1, 12, 0, 0); fflib_IMatcher matcher = new fflib_MatcherDefinitions.DatetimeAfter(fromDate, false); // When String actual = '' + matcher; // Then System.Assert.areEqual('[after "2019-01-01T12:00:00.000Z"]', actual); } @isTest private static void constructDatetimeBefore_WithNullToDatetime_ThrowsException() { try { new fflib_MatcherDefinitions.DatetimeBefore(null, true); System.Assert.fail('Expected exception'); } catch (fflib_ApexMocks.ApexMocksException e) { System.Assert.areEqual('Arg cannot be null: null', e.getMessage()); } } @isTest private static void constructDatetimeBefore_WithNullInclusive_ThrowsException() { try { new fflib_MatcherDefinitions.DatetimeBefore(System.now(), null); System.Assert.fail('Expected exception'); } catch (fflib_ApexMocks.ApexMocksException e) { System.Assert.areEqual('Arg cannot be null: null', e.getMessage()); } } @isTest private static void whenDatetimeBeforeMatchesWithoutInclusiveShouldReturnCorrectResults() { fflib_IMatcher matcher = new fflib_MatcherDefinitions.DatetimeBefore(NOW, false); System.Assert.isFalse(matcher.matches(null)); System.Assert.isFalse(matcher.matches('bob')); System.Assert.isFalse(matcher.matches(NOW.addSeconds(1))); System.Assert.isFalse(matcher.matches(NOW)); System.Assert.isTrue(matcher.matches(NOW.addSeconds(-1))); } @isTest private static void whenDatetimeBeforeMatchesWithInclusiveShouldReturnCorrectResults() { fflib_IMatcher matcher = new fflib_MatcherDefinitions.DatetimeBefore(NOW, true); System.Assert.isFalse(matcher.matches(null)); System.Assert.isFalse(matcher.matches('bob')); System.Assert.isFalse(matcher.matches(NOW.addSeconds(1))); System.Assert.isTrue(matcher.matches(NOW)); System.Assert.isTrue(matcher.matches(NOW.addSeconds(-1))); } @isTest private static void whenDatetimeBeforeWithInclusiveToStringReturnsExpectedString() { // Given DateTime toDate = DateTime.newInstanceGmt(2019, 1, 1, 12, 0, 0); fflib_IMatcher matcher = new fflib_MatcherDefinitions.DatetimeBefore(toDate, true); // When String actual = '' + matcher; // Then System.Assert.areEqual('[on or before "2019-01-01T12:00:00.000Z"]', actual); } @isTest private static void whenDatetimeBeforeWithNotInclusiveToStringReturnsExpectedString() { // Given DateTime toDate = DateTime.newInstanceGmt(2019, 1, 1, 12, 0, 0); fflib_IMatcher matcher = new fflib_MatcherDefinitions.DatetimeBefore(toDate, false); // When String actual = '' + matcher; // Then System.Assert.areEqual('[before "2019-01-01T12:00:00.000Z"]', actual); } @isTest private static void constructDatetimeBetween_WithNullFromDatetime_ThrowsException() { try { new fflib_MatcherDefinitions.DatetimeBetween(null, true, System.now(), true); System.Assert.fail('Expected exception'); } catch (fflib_ApexMocks.ApexMocksException e) { System.Assert.areEqual('Arg cannot be null: null', e.getMessage()); } } @isTest private static void constructDatetimeBetween_WithNullToDatetime_ThrowsException() { try { new fflib_MatcherDefinitions.DatetimeBetween(System.now(), true, null, true); System.Assert.fail('Expected exception'); } catch (fflib_ApexMocks.ApexMocksException e) { System.Assert.areEqual('Arg cannot be null: null', e.getMessage()); } } @isTest private static void constructDatetimeBetween_WithNullInclusiveFrom_ThrowsException() { try { new fflib_MatcherDefinitions.DatetimeBetween(System.now(), null, System.now(), true); System.Assert.fail('Expected exception'); } catch (fflib_ApexMocks.ApexMocksException e) { System.Assert.areEqual('Arg cannot be null: null', e.getMessage()); } } @isTest private static void constructDatetimeBetween_WithNullInclusiveTo_ThrowsException() { try { new fflib_MatcherDefinitions.DatetimeBetween(System.now(), true, System.now(), null); System.Assert.fail('Expected exception'); } catch (fflib_ApexMocks.ApexMocksException e) { System.Assert.areEqual('Arg cannot be null: null', e.getMessage()); } } @isTest private static void whenDatetimeBetweenMatchesWithInclusiveFromWithoutInclusiveToShouldReturnCorrectResults() { fflib_IMatcher matcher = new fflib_MatcherDefinitions.DatetimeBetween(NOW.addSeconds(-1), true, NOW.addSeconds(1), false); System.Assert.isFalse(matcher.matches(null)); System.Assert.isFalse(matcher.matches('bob')); System.Assert.isFalse(matcher.matches(NOW.addSeconds(-2))); System.Assert.isFalse(matcher.matches(NOW.addSeconds(1))); System.Assert.isTrue(matcher.matches(NOW.addSeconds(-1))); System.Assert.isTrue(matcher.matches(NOW)); } @isTest private static void whenDatetimeBetweenMatchesWithInclusiveToWithoutInclusiveFromShouldReturnCorrectResults() { fflib_IMatcher matcher = new fflib_MatcherDefinitions.DatetimeBetween(NOW.addSeconds(-1), false, NOW.addSeconds(1), true); System.Assert.isFalse(matcher.matches(null)); System.Assert.isFalse(matcher.matches('bob')); System.Assert.isFalse(matcher.matches(NOW.addSeconds(2))); System.Assert.isFalse(matcher.matches(NOW.addSeconds(-1))); System.Assert.isTrue(matcher.matches(NOW)); System.Assert.isTrue(matcher.matches(NOW.addSeconds(1))); } @isTest private static void whenDatetimeBetweenWithInclusiveToStringReturnsExpectedString() { // Given DateTime fromDate = DateTime.newInstanceGmt(2019, 1, 1, 12, 0, 0); DateTime toDate = DateTime.newInstanceGmt(2019, 1, 3, 12, 0, 0); fflib_IMatcher matcher = new fflib_MatcherDefinitions.DatetimeBetween(fromDate, true, toDate, true); // When String actual = '' + matcher; // Then System.Assert.areEqual('[on or after "2019-01-01T12:00:00.000Z" and on or before "2019-01-03T12:00:00.000Z"]', actual); } @isTest private static void whenDatetimeBetweenWithNotInclusiveToStringReturnsExpectedString() { // Given DateTime fromDate = DateTime.newInstanceGmt(2019, 1, 1, 12, 0, 0); DateTime toDate = DateTime.newInstanceGmt(2019, 1, 3, 12, 0, 0); fflib_IMatcher matcher = new fflib_MatcherDefinitions.DatetimeBetween(fromDate, false, toDate, false); // When String actual = '' + matcher; // Then System.Assert.areEqual('[after "2019-01-01T12:00:00.000Z" and before "2019-01-03T12:00:00.000Z"]', actual); } @isTest private static void constructDecimalBetween_WithNullLower_ThrowsException() { try { new fflib_MatcherDefinitions.DecimalBetween(null, true, 123, true); System.Assert.fail('Expected exception'); } catch (fflib_ApexMocks.ApexMocksException e) { System.Assert.areEqual('Arg cannot be null: null', e.getMessage()); } } @isTest private static void constructDecimalBetween_WithNullInclusiveLower_ThrowsException() { try { new fflib_MatcherDefinitions.DecimalBetween(123, null, 123, true); System.Assert.fail('Expected exception'); } catch (fflib_ApexMocks.ApexMocksException e) { System.Assert.areEqual('Arg cannot be null: null', e.getMessage()); } } @isTest private static void constructDecimalBetween_WithNullUpper_ThrowsException() { try { new fflib_MatcherDefinitions.DecimalBetween(123, true, null, true); System.Assert.fail('Expected exception'); } catch (fflib_ApexMocks.ApexMocksException e) { System.Assert.areEqual('Arg cannot be null: null', e.getMessage()); } } @isTest private static void constructDecimalBetween_WithNullInclusiveUpper_ThrowsException() { try { new fflib_MatcherDefinitions.DecimalBetween(123, true, 123, null); System.Assert.fail('Expected exception'); } catch (fflib_ApexMocks.ApexMocksException e) { System.Assert.areEqual('Arg cannot be null: null', e.getMessage()); } } @isTest private static void whenDecimalBetweenMatchesShouldReturnCorrectResults() { Integer lower = 5; Integer upper = 10; fflib_IMatcher exLowerExUpper = new fflib_MatcherDefinitions.DecimalBetween(lower, false, upper, false); fflib_IMatcher exLowerInUpper = new fflib_MatcherDefinitions.DecimalBetween(lower, false, upper, true); fflib_IMatcher inLowerExUpper = new fflib_MatcherDefinitions.DecimalBetween(lower, true, upper, false); fflib_IMatcher inLowerInUpper = new fflib_MatcherDefinitions.DecimalBetween(lower, true, upper, true); //Exclusive lower, exclusive upper System.Assert.isFalse(exLowerExUpper.matches(lower - 1)); System.Assert.isFalse(exLowerExUpper.matches(lower)); System.Assert.isTrue(exLowerExUpper.matches(lower + 1)); System.Assert.isTrue(exLowerExUpper.matches(upper - 1)); System.Assert.isFalse(exLowerExUpper.matches(upper)); System.Assert.isFalse(exLowerExUpper.matches(upper + 1)); System.Assert.isFalse(exLowerExUpper.matches(null)); System.Assert.isFalse(exLowerExUpper.matches('NotADecimal')); //Exclusive lower, inclusive upper System.Assert.isFalse(exLowerInUpper.matches(lower - 1)); System.Assert.isFalse(exLowerInUpper.matches(lower)); System.Assert.isTrue(exLowerInUpper.matches(lower + 1)); System.Assert.isTrue(exLowerInUpper.matches(upper - 1)); System.Assert.isTrue(exLowerInUpper.matches(upper)); System.Assert.isFalse(exLowerInUpper.matches(upper + 1)); System.Assert.isFalse(exLowerInUpper.matches(null)); System.Assert.isFalse(exLowerInUpper.matches('NotADecimal')); //Inclusive lower, exclusive upper System.Assert.isFalse(inLowerExUpper.matches(lower - 1)); System.Assert.isTrue(inLowerExUpper.matches(lower)); System.Assert.isTrue(inLowerExUpper.matches(lower + 1)); System.Assert.isTrue(inLowerExUpper.matches(upper - 1)); System.Assert.isFalse(inLowerExUpper.matches(upper)); System.Assert.isFalse(inLowerExUpper.matches(upper + 1)); System.Assert.isFalse(inLowerExUpper.matches(null)); System.Assert.isFalse(inLowerExUpper.matches('NotADecimal')); //Inclusive lower, inclusive upper System.Assert.isFalse(inLowerInUpper.matches(lower - 1)); System.Assert.isTrue(inLowerInUpper.matches(lower)); System.Assert.isTrue(inLowerInUpper.matches(lower + 1)); System.Assert.isTrue(inLowerInUpper.matches(upper - 1)); System.Assert.isTrue(inLowerInUpper.matches(upper)); System.Assert.isFalse(inLowerInUpper.matches(upper + 1)); System.Assert.isFalse(inLowerInUpper.matches(null)); System.Assert.isFalse(inLowerInUpper.matches('NotADecimal')); } @isTest private static void whenDecimalBetweenToStringReturnsExpectedString() { Integer lower = 5; Integer upper = 10; List formatList = new List{lower, upper}; System.Assert.areEqual(String.format('greater than {0} and less than {1}', formatList), '' + new fflib_MatcherDefinitions.DecimalBetween(lower, false, upper, false)); System.Assert.areEqual(String.format('greater than {0} and less than or equal to {1}', formatList), '' + new fflib_MatcherDefinitions.DecimalBetween(lower, false, upper, true)); System.Assert.areEqual(String.format('greater than or equal to {0} and less than {1}', formatList), '' + new fflib_MatcherDefinitions.DecimalBetween(lower, true, upper, false)); System.Assert.areEqual(String.format('greater than or equal to {0} and less than or equal to {1}', formatList), '' + new fflib_MatcherDefinitions.DecimalBetween(lower, true, upper, true)); } @isTest private static void constructDecimalLessThan_WithNullToMatch_ThrowsException() { try { new fflib_MatcherDefinitions.DecimalLessThan(null, true); System.Assert.fail('Expected exception'); } catch (fflib_ApexMocks.ApexMocksException e) { System.Assert.areEqual('Arg cannot be null: null', e.getMessage()); } } @isTest private static void constructDecimalLessThan_WithNullInclusive_ThrowsException() { try { new fflib_MatcherDefinitions.DecimalLessThan(123, null); System.Assert.fail('Expected exception'); } catch (fflib_ApexMocks.ApexMocksException e) { System.Assert.areEqual('Arg cannot be null: null', e.getMessage()); } } @isTest private static void whenDecimalLessThanMatchesShouldReturnCorrectResults() { Integer toMatch = 5; fflib_IMatcher exclusive = new fflib_MatcherDefinitions.DecimalLessThan(toMatch, false); fflib_IMatcher inclusive = new fflib_MatcherDefinitions.DecimalLessThan(toMatch, true); //Exclusive System.Assert.isTrue(exclusive.matches(toMatch - 1)); System.Assert.isFalse(exclusive.matches(toMatch)); System.Assert.isFalse(exclusive.matches(toMatch + 1)); System.Assert.isFalse(exclusive.matches(null)); System.Assert.isFalse(exclusive.matches('NotADecimal')); //Inclusive System.Assert.isTrue(inclusive.matches(toMatch - 1)); System.Assert.isTrue(inclusive.matches(toMatch)); System.Assert.isFalse(inclusive.matches(toMatch + 1)); System.Assert.isFalse(inclusive.matches(null)); System.Assert.isFalse(inclusive.matches('NotADecimal')); } @isTest private static void whenDecimalLessThanToStringReturnsExpectedString() { Integer toMatch = 5; System.Assert.areEqual('[less than or equal to ' + toMatch + ']', '' + new fflib_MatcherDefinitions.DecimalLessThan(toMatch, true)); System.Assert.areEqual('[less than ' + toMatch + ']', '' + new fflib_MatcherDefinitions.DecimalLessThan(toMatch, false)); } @isTest private static void constructDecimalMoreThan_WithNullToMatch_ThrowsException() { try { new fflib_MatcherDefinitions.DecimalMoreThan(null, true); System.Assert.fail('Expected exception'); } catch (fflib_ApexMocks.ApexMocksException e) { System.Assert.areEqual('Arg cannot be null: null', e.getMessage()); } } @isTest private static void constructDecimalMoreThan_WithNullInclusive_ThrowsException() { try { new fflib_MatcherDefinitions.DecimalMoreThan(123, null); System.Assert.fail('Expected exception'); } catch (fflib_ApexMocks.ApexMocksException e) { System.Assert.areEqual('Arg cannot be null: null', e.getMessage()); } } @isTest private static void whenDecimalMoreThanMatchesShouldReturnCorrectResults() { Integer toMatch = 5; fflib_IMatcher exclusive = new fflib_MatcherDefinitions.DecimalMoreThan(toMatch, false); fflib_IMatcher inclusive = new fflib_MatcherDefinitions.DecimalMoreThan(toMatch, true); //Exclusive System.Assert.isFalse(exclusive.matches(toMatch - 1)); System.Assert.isFalse(exclusive.matches(toMatch)); System.Assert.isTrue(exclusive.matches(toMatch + 1)); System.Assert.isFalse(exclusive.matches(null)); System.Assert.isFalse(exclusive.matches('NotADecimal')); //Inclusive System.Assert.isFalse(inclusive.matches(toMatch - 1)); System.Assert.isTrue(inclusive.matches(toMatch)); System.Assert.isTrue(inclusive.matches(toMatch + 1)); System.Assert.isFalse(inclusive.matches(null)); System.Assert.isFalse(inclusive.matches('NotADecimal')); } @isTest private static void whenDecimalMoreThanToStringReturnsExpectedString() { Integer toMatch = 5; System.Assert.areEqual('[greater than or equal to ' + toMatch + ']', '' + new fflib_MatcherDefinitions.DecimalMoreThan(toMatch, true)); System.Assert.areEqual('[greater than ' + toMatch + ']', '' + new fflib_MatcherDefinitions.DecimalMoreThan(toMatch, false)); } @isTest private static void constructFieldSetEquivalentTo_WithNullFieldSet_ThrowsException() { try { new fflib_MatcherDefinitions.FieldSetEquivalentTo(null); System.Assert.fail('Expected exception'); } catch (fflib_ApexMocks.ApexMocksException e) { System.Assert.areEqual('Arg cannot be null: null', e.getMessage()); } } @isTest private static void whenFieldSetEquivalentToWithoutFieldSetShouldNeverMatch() { //Cheap test to maintain 100% code coverage, even in orgs without field sets defined. fflib_IMatcher matcher = new fflib_MatcherDefinitions.FieldSetEquivalentTo(); System.Assert.isFalse(matcher.matches(null)); } @isTest private static void whenFieldSetEquivalentToMatchesShouldReturnCorrectResults() { Schema.FieldSet anyFieldSet = fflib_ApexMocksUtilsTest.findAnyFieldSet(); if (anyFieldSet == null) { return; } fflib_IMatcher matcher = new fflib_MatcherDefinitions.FieldSetEquivalentTo(anyFieldSet); System.Assert.isFalse(matcher.matches(null)); System.Assert.isFalse(matcher.matches('hello')); System.Assert.isTrue(matcher.matches(anyFieldSet)); } @isTest private static void whenFieldSetEquivalentToToStringReturnsExpectedString() { Schema.FieldSet anyFieldSet = fflib_ApexMocksUtilsTest.findAnyFieldSet(); if (anyFieldSet == null) { return; } Set fieldSetMembers = new Set((anyFieldSet).getFields()); System.Assert.areEqual('[FieldSet with fields ' + JSON.serialize(fieldSetMembers, false) + ']', '' + new fflib_MatcherDefinitions.FieldSetEquivalentTo(anyFieldSet)); } @isTest private static void whenIsNullMatchesShouldReturnCorrectResults() { fflib_IMatcher matcher = new fflib_MatcherDefinitions.IsNull(); System.Assert.isFalse(matcher.matches('bob')); System.Assert.isTrue(matcher.matches(null)); } @isTest private static void whenIsNullToStringReturnsExpectedString() { System.Assert.areEqual('[is null]', '' + new fflib_MatcherDefinitions.IsNull()); } @isTest private static void whenIsNotNullMatchesShouldReturnCorrectResults() { fflib_IMatcher matcher = new fflib_MatcherDefinitions.IsNotNull(); System.Assert.isFalse(matcher.matches(null)); System.Assert.isTrue(matcher.matches('bob')); } @isTest private static void whenIsNotNullToStringReturnsExpectedString() { System.Assert.areEqual('[is not null]', '' + new fflib_MatcherDefinitions.IsNotNull()); } @isTest private static void whenListContainsMatchesShouldReturnCorrectResults() { List names = new List{ 'bob', 'tom', 'fred' }; List empty = new List(); System.Assert.isFalse(new fflib_MatcherDefinitions.ListContains('fred').matches(null)); System.Assert.isFalse(new fflib_MatcherDefinitions.ListContains('fred').matches(empty)); System.Assert.isFalse(new fflib_MatcherDefinitions.ListContains('jack').matches(names)); System.Assert.isTrue(new fflib_MatcherDefinitions.ListContains('fred').matches(names)); System.Assert.isFalse(new fflib_MatcherDefinitions.ListContains('fred').matches('NotAList')); } @isTest private static void whenListContainsToStringReturnsExpectedString() { System.Assert.areEqual('[list containing "hello"]', '' + new fflib_MatcherDefinitions.ListContains('hello')); } @isTest private static void whenListIsEmptyMatchesShouldReturnCorrectResults() { fflib_IMatcher matcher = new fflib_MatcherDefinitions.ListIsEmpty(); List names = new List{ 'bob', 'tom', 'fred' }; List empty = new List(); System.Assert.isFalse(matcher.matches(null)); System.Assert.isFalse(matcher.matches(names)); System.Assert.isTrue(matcher.matches(empty)); System.Assert.isFalse(matcher.matches('NotAList')); } @isTest private static void whenListIsEmptyToStringReturnsExpectedString() { System.Assert.areEqual('[empty list]', '' + new fflib_MatcherDefinitions.ListIsEmpty()); } @isTest private static void constructSObjectOfType_WithNullArg_ThrowsException() { try { new fflib_MatcherDefinitions.SObjectOfType(null); System.Assert.fail('Expected exception'); } catch (fflib_ApexMocks.ApexMocksException e) { System.Assert.areEqual('Arg cannot be null: null', e.getMessage()); } } @isTest private static void whenSObjectOfTypeMatchesShouldReturnCorrectResults() { fflib_IMatcher matcher = new fflib_MatcherDefinitions.SObjectOfType(ACCOUNT_OBJECT_TYPE); System.Assert.isFalse(matcher.matches(null)); System.Assert.isFalse(matcher.matches(OPPORTUNITY_OBJECT_TYPE.newSObject())); System.Assert.isFalse(matcher.matches('NotASObject')); System.Assert.isTrue(matcher.matches(ACCOUNT_OBJECT_TYPE.newSObject())); System.Assert.isTrue(matcher.matches(ACCOUNT_RECORD)); } @isTest private static void whenSObjectOfTypeToStringReturnsExpectedString() { System.Assert.areEqual('[SObject of type Account]', '' + new fflib_MatcherDefinitions.SObjectOfType(ACCOUNT_OBJECT_TYPE)); } @isTest private static void constructSObjectWith_WithNullArg_ThrowsException() { try { new fflib_MatcherDefinitions.SObjectWith(null); System.Assert.fail('Expected exception'); } catch (fflib_ApexMocks.ApexMocksException e) { System.Assert.areEqual('Arg cannot be null/empty: null', e.getMessage()); } } @isTest private static void constructSObjectWith_WithEmptyArg_ThrowsException() { try { new fflib_MatcherDefinitions.SObjectWith(new Map()); System.Assert.fail('Expected exception'); } catch (fflib_ApexMocks.ApexMocksException e) { System.Assert.areEqual('Arg cannot be null/empty: {}', e.getMessage()); } } @isTest private static void whenSObjectWithMatchesShouldReturnCorrectResults() { Map fields = ACCOUNT_OBJECT_TYPE.getDescribe().fields.getMap(); Schema.SObjectField idField = fields.get('Id'); Schema.SObjectField nameField = fields.get('Name'); Schema.SObjectField createdDateField = fields.get('CreatedDate'); Map queriedFieldValues = new Map { idField => ACCOUNT_RECORD.Id, nameField => ACCOUNT_RECORD.get('Name') }; Map notQueriedFieldValues = new Map { createdDateField => System.now() }; fflib_IMatcher matcher = new fflib_MatcherDefinitions.SObjectWith(queriedFieldValues); System.Assert.isFalse(matcher.matches(null)); System.Assert.isFalse(matcher.matches(OPPORTUNITY_OBJECT_TYPE.newSObject())); System.Assert.isFalse(matcher.matches(ACCOUNT_OBJECT_TYPE.newSObject())); System.Assert.isFalse(matcher.matches('NotASObject')); System.Assert.isTrue(matcher.matches(ACCOUNT_RECORD)); System.Assert.isFalse(new fflib_MatcherDefinitions.SObjectWith(notQueriedFieldValues).matches(ACCOUNT_RECORD)); } @isTest private static void whenSObjectWithToStringReturnsExpectedString() { fflib_IMatcher matcher = new fflib_MatcherDefinitions.SObjectWith(new Map{ Account.Name => 'Test' }); System.Assert.areEqual('[SObject with fields {"Name":"Test"}]', '' + matcher); } @isTest private static void whenSObjectsWithInOrderMatchesShouldReturnCorrectResults() { Map fields = GROUP_OBJECT_TYPE.getDescribe().fields.getMap(); Schema.SObjectField idField = fields.get('Id'); Schema.SObjectField nameField = fields.get('Name'); Schema.SObjectField createdDateField = fields.get('CreatedDate'); list> queriedFieldValues = new list> { new map { idField => GROUP_RECORDS[0].Id, nameField => GROUP_RECORDS[0].get('Name') }, new map { idField => GROUP_RECORDS[1].Id, nameField => GROUP_RECORDS[1].get('Name') } }; list> failingFieldValues = new list> { new map { idField => GROUP_RECORDS[0].Id, nameField => GROUP_RECORDS[0].get('Name') }, new map { idField => GROUP_RECORDS[1].Id, nameField => GROUP_RECORDS[1].get('Name') + 'test' } }; list> notQueriedFieldValues = new list> { new map { createdDateField => System.now() }, new map { createdDateField => System.now() } }; fflib_IMatcher matcher = new fflib_MatcherDefinitions.SObjectsWith(queriedFieldValues); System.Assert.isFalse(matcher.matches(null)); System.Assert.isFalse(matcher.matches(new list { OPPORTUNITY_OBJECT_TYPE.newSObject(), OPPORTUNITY_OBJECT_TYPE.newSObject() } )); System.Assert.isFalse(matcher.matches(new list { GROUP_OBJECT_TYPE.newSObject(), GROUP_OBJECT_TYPE.newSObject() } ),'sObjectsWith arity agrees but arg doesn\'t'); System.Assert.isFalse(matcher.matches('NotAListofSObject')); System.Assert.isTrue(matcher.matches(GROUP_RECORDS),'toMatch and args have same arity and in same order'); System.Assert.isTrue (!matcher.matches(new list {GROUP_RECORDS[1],GROUP_RECORDS[0]}), 'sObjectsWith toMatch and args have same arity but args are in different order than toMatch') ; System.Assert.isFalse(new fflib_MatcherDefinitions.SObjectsWith(notQueriedFieldValues).matches(GROUP_RECORDS)); System.Assert.isFalse(new fflib_MatcherDefinitions.SObjectsWith(failingFieldValues).matches(GROUP_RECORDS)); } @isTest private static void whenSObjectsInAnyOrderWithMatchesShouldReturnCorrectResults() { Map fields = GROUP_OBJECT_TYPE.getDescribe().fields.getMap(); Schema.SObjectField idField = fields.get('Id'); Schema.SObjectField nameField = fields.get('Name'); Schema.SObjectField createdDateField = fields.get('CreatedDate'); list> queriedFieldValues = new list> { new map { idField => GROUP_RECORDS[0].Id, nameField => GROUP_RECORDS[0].get('Name') }, new map { idField => GROUP_RECORDS[1].Id, nameField => GROUP_RECORDS[1].get('Name') } }; list> notQueriedFieldValues = new list> { new map { createdDateField => System.now() }, new map { createdDateField => System.now() } }; fflib_IMatcher matcher = new fflib_MatcherDefinitions.SObjectsWith(queriedFieldValues,false); // any order System.Assert.isFalse(matcher.matches(null)); System.Assert.isFalse(matcher.matches(new list { OPPORTUNITY_OBJECT_TYPE.newSObject(), OPPORTUNITY_OBJECT_TYPE.newSObject() } )); System.Assert.isFalse(matcher.matches(new list { GROUP_OBJECT_TYPE.newSObject(), GROUP_OBJECT_TYPE.newSObject() } ),'sObjectsWith arity agrees but arg doesn\'t match matcher'); System.Assert.isFalse(matcher.matches('NotAListofSObject')); System.Assert.isTrue(matcher.matches(GROUP_RECORDS),'toMatch and args have same arity and in same order. Match should be OK'); System.Assert.isTrue (matcher.matches(new list {GROUP_RECORDS[1],GROUP_RECORDS[0]}), 'sObjectsWith toMatch and args have same arity but args are in diff order than matcher. Should be OK') ; System.Assert.isFalse(new fflib_MatcherDefinitions.SObjectsWith(notQueriedFieldValues,false).matches(GROUP_RECORDS)); } @isTest private static void whenSObjectsWithToStringReturnsExpectedString() { List> toMatch = new List>{ new Map { Account.Name => 'Test' } }; System.Assert.areEqual('[ordered SObjects with [{"Name":"Test"}]]', '' + new fflib_MatcherDefinitions.SObjectsWith(toMatch, true)); System.Assert.areEqual('[unordered SObjects with [{"Name":"Test"}]]', '' + new fflib_MatcherDefinitions.SObjectsWith(toMatch, false)); } @isTest private static void whenSObjectsWithDifferentArityMatchesShouldReturnFalse() { List> toMatch = new List>{ new Map { Account.Name => 'Test' } }; Boolean matchResult = new fflib_MatcherDefinitions.SObjectsWith(toMatch).matches(new List{}); System.Assert.areEqual(matchResult, false); } @isTest private static void constructSObjectsWith_WithNullArg_ThrowsException() { try { new fflib_MatcherDefinitions.SObjectsWith(null); System.Assert.fail('Expected exception'); } catch (fflib_ApexMocks.ApexMocksException e) { System.Assert.areEqual('Arg cannot be null/empty/other than list of map: null', e.getMessage()); } } @isTest private static void constructSObjectWithId_WithNullArg_ThrowsException() { try { new fflib_MatcherDefinitions.SObjectWithId(null); System.Assert.fail('Expected exception'); } catch (fflib_ApexMocks.ApexMocksException e) { System.Assert.areEqual('Arg cannot be null: null', e.getMessage()); } } @isTest private static void whenSObjectWithIdMatchesShouldReturnCorrectResults() { fflib_IMatcher matcher = new fflib_MatcherDefinitions.SObjectWithId(ACCOUNT_RECORD.Id); System.Assert.isFalse(matcher.matches(null)); System.Assert.isFalse(matcher.matches(OPPORTUNITY_OBJECT_TYPE.newSObject())); System.Assert.isFalse(matcher.matches(ACCOUNT_OBJECT_TYPE.newSObject())); System.Assert.isFalse(matcher.matches('NotASObject')); System.Assert.isTrue(matcher.matches(ACCOUNT_RECORD)); } @isTest private static void whenSObjectWithIdToStringReturnsExpectedString() { Id recordId = '001000000000001AAA'; System.Assert.areEqual('[SObject with Id "001000000000001AAA"]', '' + new fflib_MatcherDefinitions.SObjectWithId(recordId)); } @isTest private static void constructSObjectWithName_WithNullArg_ThrowsException() { try { new fflib_MatcherDefinitions.SObjectWithName(null); System.Assert.fail('Expected exception'); } catch (fflib_ApexMocks.ApexMocksException e) { System.Assert.areEqual('Arg cannot be null: null', e.getMessage()); } } @isTest private static void whenSObjectWithNameMatchesShouldReturnCorrectResults() { fflib_IMatcher matcher = new fflib_MatcherDefinitions.SObjectWithName((String)ACCOUNT_RECORD.get('Name')); System.Assert.isFalse(matcher.matches(null)); System.Assert.isFalse(matcher.matches(OPPORTUNITY_OBJECT_TYPE.newSObject())); System.Assert.isFalse(matcher.matches(ACCOUNT_OBJECT_TYPE.newSObject())); System.Assert.isFalse(matcher.matches('NotASObject')); System.Assert.isTrue(matcher.matches(ACCOUNT_RECORD)); } @isTest private static void whenSObjectWithNameToStringReturnsExpectedString() { System.Assert.areEqual('[SObject with Name "Test"]', '' + new fflib_MatcherDefinitions.SObjectWithName('Test')); } @isTest private static void whenStringContainsMatchesShouldReturnCorrectResults() { fflib_IMatcher matcher = new fflib_MatcherDefinitions.StringContains('bob'); System.Assert.isFalse(matcher.matches(7)); System.Assert.isFalse(matcher.matches(null)); System.Assert.isFalse(matcher.matches('')); System.Assert.isFalse(matcher.matches('blob')); System.Assert.isTrue(matcher.matches('bob')); System.Assert.isTrue(matcher.matches('bobby')); } @isTest private static void constructStringContains_WithNullArg_ThrowsException() { try { new fflib_MatcherDefinitions.StringContains(null); System.Assert.fail('Expected exception'); } catch (fflib_ApexMocks.ApexMocksException e) { System.Assert.areEqual('Arg cannot be null: null', e.getMessage()); } } @isTest private static void whenStringContainsToStringReturnsExpectedStrings() { System.Assert.areEqual('[contains "hello"]', '' + new fflib_MatcherDefinitions.StringContains('hello')); } @isTest private static void whenStringEndsWithMatchesShouldReturnCorrectResults() { fflib_IMatcher matcher = new fflib_MatcherDefinitions.StringEndsWith('bob'); System.Assert.isFalse(matcher.matches(7)); System.Assert.isFalse(matcher.matches(null)); System.Assert.isFalse(matcher.matches('')); System.Assert.isFalse(matcher.matches('bobby')); System.Assert.isTrue(matcher.matches('bob')); System.Assert.isTrue(matcher.matches('jimbob')); } @isTest private static void constructStringEndsWith_WithNullArg_ThrowsException() { try { new fflib_MatcherDefinitions.StringEndsWith(null); System.Assert.fail('Expected exception'); } catch (fflib_ApexMocks.ApexMocksException e) { System.Assert.areEqual('Arg cannot be null: null', e.getMessage()); } } @isTest private static void whenStringEndsWithToStringReturnsExpectedStrings() { System.Assert.areEqual('[ends with "hello"]', '' + new fflib_MatcherDefinitions.StringEndsWith('hello')); } @isTest private static void whenIsBlankWithMatchesShouldReturnCorrectResults() { fflib_IMatcher matcher = new fflib_MatcherDefinitions.StringIsBlank(); System.Assert.isFalse(matcher.matches(7)); System.Assert.isFalse(matcher.matches('bob')); System.Assert.isTrue(matcher.matches(null)); System.Assert.isTrue(matcher.matches('')); } @isTest private static void whenStringIsBlankToStringReturnsExpectedStrings() { System.Assert.areEqual('[blank String]', '' + new fflib_MatcherDefinitions.StringIsBlank()); } @isTest private static void whenIsNotBlankWithMatchesShouldReturnCorrectResults() { fflib_IMatcher matcher = new fflib_MatcherDefinitions.StringIsNotBlank(); System.Assert.isFalse(matcher.matches(7)); System.Assert.isFalse(matcher.matches(null)); System.Assert.isFalse(matcher.matches('')); System.Assert.isTrue(matcher.matches('bob')); } @isTest private static void whenStringIsNotBlankToStringReturnsExpectedStrings() { System.Assert.areEqual('[non-blank String]', '' + new fflib_MatcherDefinitions.StringIsNotBlank()); } @isTest private static void whenStringMatchesMatchesShouldReturnCorrectResults() { fflib_IMatcher matcher = new fflib_MatcherDefinitions.StringMatches('(b|m)o[a-z]*'); System.Assert.isFalse(matcher.matches(7)); System.Assert.isFalse(matcher.matches(null)); System.Assert.isFalse(matcher.matches('bib')); System.Assert.isFalse(matcher.matches('jimbob')); System.Assert.isFalse(matcher.matches('tom')); System.Assert.isFalse(matcher.matches('bob1')); System.Assert.isTrue(matcher.matches('bobby')); System.Assert.isTrue(matcher.matches('mo')); } @isTest private static void whenStringMatchesToStringReturnsExpectedStrings() { System.Assert.areEqual('[matches regex "hello"]', '' + new fflib_MatcherDefinitions.StringMatches('hello')); } @isTest private static void constructStringMatches_WithNullArg_ThrowsException() { try { new fflib_MatcherDefinitions.StringMatches(null); System.Assert.fail('Expected exception'); } catch (fflib_ApexMocks.ApexMocksException e) { System.Assert.areEqual('Arg cannot be null: null', e.getMessage()); } } @isTest private static void whenStringStartsWithMatchesShouldReturnCorrectResults() { fflib_IMatcher matcher = new fflib_MatcherDefinitions.StringStartsWith('bob'); System.Assert.isFalse(matcher.matches(7)); System.Assert.isFalse(matcher.matches(null)); System.Assert.isFalse(matcher.matches('')); System.Assert.isFalse(matcher.matches('jimbob')); System.Assert.isTrue(matcher.matches('bob')); System.Assert.isTrue(matcher.matches('bobby')); } @isTest private static void whenStringStartsWithToStringReturnsExpectedStrings() { System.Assert.areEqual('[starts with "hello"]', '' + new fflib_MatcherDefinitions.StringStartsWith('hello')); } @isTest private static void constructStringStartsWith_WithNullArg_ThrowsException() { try { new fflib_MatcherDefinitions.StringStartsWith(null); System.Assert.fail('Expected exception'); } catch (fflib_ApexMocks.ApexMocksException e) { System.Assert.areEqual('Arg cannot be null: null', e.getMessage()); } } @isTest private static void whenJSONExceptionOccursStringifyShouldReturnsObjectToString() { // SObjectField object definitely can't be serialized by JSON.serialize() method Schema.SObjectField sObjField = Account.Description; System.Assert.areEqual('' + sObjField, fflib_MatcherDefinitions.stringify(sObjField)); } private class StringMatcher implements fflib_IMatcher { private final String value; public StringMatcher(String value) { this.value = value; } public Boolean matches(Object arg) { return true; } public override String toString() { return '"' + value + '"'; } } } ================================================ FILE: sfdx-source/apex-mocks/test/classes/fflib_MatcherDefinitionsTest.cls-meta.xml ================================================ 63.0 ================================================ FILE: sfdx-source/apex-mocks/test/classes/fflib_MethodArgValuesTest.cls ================================================ /** * Copyright (c) 2014-2016, FinancialForce.com, inc * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * - Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * - Neither the name of the FinancialForce.com, inc nor the names of its contributors * may be used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ @isTest public with sharing class fflib_MethodArgValuesTest { @isTest private static void equalsReturnsExpectedResults() { //Given fflib_MethodArgValues qm1 = new fflib_MethodArgValues(new List{ 'hello' }); fflib_MethodArgValues qm2 = new fflib_MethodArgValues(new List{ 'hello' }); fflib_MethodArgValues qm3 = new fflib_MethodArgValues(new List{ 'hi' }); fflib_MethodArgValues qm4 = new fflib_MethodArgValues(new List{ 'hello', 'hello', 'hello' }); fflib_MethodArgValues qm5 = new fflib_MethodArgValues(new List()); fflib_MethodArgValues qm6 = new fflib_MethodArgValues(null); //When/thens System.Assert.areEqual(qm1, qm1); System.Assert.areEqual(qm1, qm2); System.Assert.areNotEqual(qm1, qm3); System.Assert.areNotEqual(qm1, qm4); System.Assert.areNotEqual(qm1, qm5); System.Assert.areNotEqual(qm1, qm6); System.Assert.areEqual(qm2, qm2); System.Assert.areNotEqual(qm2, qm3); System.Assert.areNotEqual(qm2, qm4); System.Assert.areNotEqual(qm2, qm5); System.Assert.areNotEqual(qm2, qm6); System.Assert.areEqual(qm3, qm3); System.Assert.areNotEqual(qm3, qm4); System.Assert.areNotEqual(qm3, qm5); System.Assert.areNotEqual(qm3, qm6); System.Assert.areEqual(qm4, qm4); System.Assert.areNotEqual(qm4, qm5); System.Assert.areNotEqual(qm4, qm6); System.Assert.areEqual(qm5, qm5); System.Assert.areNotEqual(qm5, qm6); System.Assert.areEqual(qm6, qm6); } @isTest private static void hashCodeReturnsExpectedResults() { //Given fflib_MethodArgValues qm1 = new fflib_MethodArgValues(new List{ 'hello' }); fflib_MethodArgValues qm2 = new fflib_MethodArgValues(new List{ 'hello' }); fflib_MethodArgValues qm3 = new fflib_MethodArgValues(new List{ 'hi' }); fflib_MethodArgValues qm4 = new fflib_MethodArgValues(new List{ 'hello', 'hello', 'hello' }); fflib_MethodArgValues qm5 = new fflib_MethodArgValues(new List()); fflib_MethodArgValues qm6 = new fflib_MethodArgValues(null); //When/thens System.Assert.areEqual(qm1.hashCode(), qm1.hashCode()); System.Assert.areEqual(qm1.hashCode(), qm2.hashCode()); System.Assert.areNotEqual(qm1.hashCode(), qm3.hashCode()); System.Assert.areNotEqual(qm1.hashCode(), qm4.hashCode()); System.Assert.areNotEqual(qm1.hashCode(), qm5.hashCode()); System.Assert.areNotEqual(qm1.hashCode(), qm6.hashCode()); System.Assert.areEqual(qm2.hashCode(), qm2.hashCode()); System.Assert.areNotEqual(qm2.hashCode(), qm3.hashCode()); System.Assert.areNotEqual(qm2.hashCode(), qm4.hashCode()); System.Assert.areNotEqual(qm2.hashCode(), qm5.hashCode()); System.Assert.areNotEqual(qm2.hashCode(), qm6.hashCode()); System.Assert.areEqual(qm3.hashCode(), qm3.hashCode()); System.Assert.areNotEqual(qm3.hashCode(), qm4.hashCode()); System.Assert.areNotEqual(qm3.hashCode(), qm5.hashCode()); System.Assert.areNotEqual(qm3.hashCode(), qm6.hashCode()); System.Assert.areEqual(qm4.hashCode(), qm4.hashCode()); System.Assert.areNotEqual(qm4.hashCode(), qm5.hashCode()); System.Assert.areNotEqual(qm4.hashCode(), qm6.hashCode()); System.Assert.areEqual(qm5.hashCode(), qm5.hashCode()); System.Assert.areNotEqual(qm5.hashCode(), qm6.hashCode()); System.Assert.areEqual(qm6.hashCode(), qm6.hashCode()); } } ================================================ FILE: sfdx-source/apex-mocks/test/classes/fflib_MethodArgValuesTest.cls-meta.xml ================================================ 63.0 ================================================ FILE: sfdx-source/apex-mocks/test/classes/fflib_MyList.cls ================================================ /* Copyright (c) 2014-2017 FinancialForce.com, inc. All rights reserved. */ /** * @nodoc */ @isTest public with sharing class fflib_MyList implements IList { public interface IList { void add(String value); void add(String value1, String value2, String value3, String value4); void addMore(String value); void add(String[] value); // Test methods with the same name and number of params String get(Integer index); String get2(Integer index, String value); // This is just a method signature to allow me to test stubbing a method with multiple arguments void clear(); Boolean isEmpty(); void set(Integer index, Object value); } public void add(String[] value) { } public void add(String value) { } public void add(String value1, String value2, String value3, String value4) { } public void addMore(String value) { } public String get(Integer index) { return 'fred'; } public void clear() { } public Boolean isEmpty() { return true; } public void set(Integer index, Object value) { } public String get2(Integer index, String value) { return 'mary'; } public static String getStubClassName() { return fflib_ApexMocks.extractTypeName(new fflib_ApexMocks().mock(fflib_MyList.class)); } } ================================================ FILE: sfdx-source/apex-mocks/test/classes/fflib_MyList.cls-meta.xml ================================================ 63.0 Active ================================================ FILE: sfdx-source/apex-mocks/test/classes/fflib_QualifiedMethodAndArgValuesTest.cls ================================================ @isTest public class fflib_QualifiedMethodAndArgValuesTest { @isTest private static void equalsReturnsExpectedResults() { fflib_QualifiedMethod qm1 = new fflib_QualifiedMethod('Type1', 'Method1', new List{ Integer.class } ); fflib_MethodArgValues mav1 = new fflib_MethodArgValues(new List{ 'hello' }); Object obj1 = 'hello'; fflib_QualifiedMethodAndArgValues qmaav = new fflib_QualifiedMethodAndArgValues(qm1, mav1, obj1); fflib_QualifiedMethod qm2 = qmaav.getQualifiedMethod(); fflib_MethodArgValues mav2 = qmaav.getMethodArgValues(); Object obj2 = qmaav.getMockInstance(); String string1 = qmaav.toString(); System.Assert.areEqual(qm1, qm2); System.Assert.areEqual(mav1, mav2); System.Assert.areEqual(obj1, obj2); System.Assert.areEqual('Type1.Method1(Integer) with args: [hello]', string1); } } ================================================ FILE: sfdx-source/apex-mocks/test/classes/fflib_QualifiedMethodAndArgValuesTest.cls-meta.xml ================================================ 63.0 Active ================================================ FILE: sfdx-source/apex-mocks/test/classes/fflib_QualifiedMethodTest.cls ================================================ /* * Copyright (c) 2016-2017 FinancialForce.com, inc. All rights reserved. */ @isTest public with sharing class fflib_QualifiedMethodTest { @isTest private static void equalsReturnsExpectedResults() { //Given fflib_QualifiedMethod qm1 = new fflib_QualifiedMethod('Type1', 'Method1', new List{ Integer.class } ); fflib_QualifiedMethod qm2 = new fflib_QualifiedMethod('Type1', 'Method1', new List{ Integer.class } ); fflib_QualifiedMethod qm3 = new fflib_QualifiedMethod('Type1', 'Method1', new List{ String.class } ); fflib_QualifiedMethod qm4 = new fflib_QualifiedMethod('Type2', 'Method2', new List{ Integer.class, String.class, fflib_QualifiedMethodTest.class } ); fflib_QualifiedMethod qm5 = new fflib_QualifiedMethod('', '', new List{} ); fflib_QualifiedMethod qm6 = new fflib_QualifiedMethod(null, null, null ); //When/thens System.Assert.areEqual(qm1, qm1); System.Assert.areEqual(qm1, qm2); System.Assert.areNotEqual(qm1, qm3); System.Assert.areNotEqual(qm1, qm4); System.Assert.areNotEqual(qm1, qm5); System.Assert.areNotEqual(qm1, qm6); System.Assert.areEqual(qm2, qm2); System.Assert.areNotEqual(qm2, qm3); System.Assert.areNotEqual(qm2, qm4); System.Assert.areNotEqual(qm2, qm5); System.Assert.areNotEqual(qm2, qm6); System.Assert.areEqual(qm3, qm3); System.Assert.areNotEqual(qm3, qm4); System.Assert.areNotEqual(qm3, qm5); System.Assert.areNotEqual(qm3, qm6); System.Assert.areEqual(qm4, qm4); System.Assert.areNotEqual(qm4, qm5); System.Assert.areNotEqual(qm4, qm6); System.Assert.areEqual(qm5, qm5); System.Assert.areNotEqual(qm5, qm6); System.Assert.areEqual(qm6, qm6); } @isTest private static void hashCodeReturnsExpectedResults() { //Given fflib_QualifiedMethod qm1 = new fflib_QualifiedMethod('Type1', 'Method1', new List{ Integer.class } ); fflib_QualifiedMethod qm2 = new fflib_QualifiedMethod('Type1', 'Method1', new List{ Integer.class } ); fflib_QualifiedMethod qm3 = new fflib_QualifiedMethod('Type1', 'Method1', new List{ String.class } ); fflib_QualifiedMethod qm4 = new fflib_QualifiedMethod('Type2', 'Method2', new List{ Integer.class, String.class, fflib_QualifiedMethodTest.class } ); fflib_QualifiedMethod qm5 = new fflib_QualifiedMethod('', '', new List{} ); fflib_QualifiedMethod qm6 = new fflib_QualifiedMethod(null, null, null ); //When/thens System.Assert.areEqual(qm1.hashCode(), qm1.hashCode()); System.Assert.areEqual(qm1.hashCode(), qm2.hashCode()); System.Assert.areNotEqual(qm1.hashCode(), qm3.hashCode()); System.Assert.areNotEqual(qm1.hashCode(), qm4.hashCode()); System.Assert.areNotEqual(qm1.hashCode(), qm5.hashCode()); System.Assert.areNotEqual(qm1.hashCode(), qm6.hashCode()); System.Assert.areEqual(qm2.hashCode(), qm2.hashCode()); System.Assert.areNotEqual(qm2.hashCode(), qm3.hashCode()); System.Assert.areNotEqual(qm2.hashCode(), qm4.hashCode()); System.Assert.areNotEqual(qm2.hashCode(), qm5.hashCode()); System.Assert.areNotEqual(qm2.hashCode(), qm6.hashCode()); System.Assert.areEqual(qm3.hashCode(), qm3.hashCode()); System.Assert.areNotEqual(qm3.hashCode(), qm4.hashCode()); System.Assert.areNotEqual(qm3.hashCode(), qm5.hashCode()); System.Assert.areNotEqual(qm3.hashCode(), qm6.hashCode()); System.Assert.areEqual(qm4.hashCode(), qm4.hashCode()); System.Assert.areNotEqual(qm4.hashCode(), qm5.hashCode()); System.Assert.areNotEqual(qm4.hashCode(), qm6.hashCode()); System.Assert.areEqual(qm5.hashCode(), qm5.hashCode()); System.Assert.areNotEqual(qm5.hashCode(), qm6.hashCode()); System.Assert.areEqual(qm6.hashCode(), qm6.hashCode()); } @isTest public static void toStringReturnsExpectedResult() { System.Assert.areEqual('MyClass.MyMethod(Integer)', new fflib_QualifiedMethod('MyClass', 'MyMethod', new List{ Integer.class }).toString()); } @isTest private static void equalsReturnsExpectedResultsForHasDependentMocks() { //Given String instance = 'My object instance'; String instance2 = 'My other object instance'; fflib_QualifiedMethod qm1 = new fflib_QualifiedMethod('Type1', 'Method1', new List{ Integer.class } ); fflib_QualifiedMethod qm2 = new fflib_QualifiedMethod('Type1', 'Method1', new List{ Integer.class }, instance); fflib_QualifiedMethod qm3 = new fflib_QualifiedMethod('Type1', 'Method1', new List{ Integer.class }, instance); fflib_QualifiedMethod qm4 = new fflib_QualifiedMethod('Type1', 'Method1', new List{ Integer.class }, instance2); //When/thens fflib_ApexMocksConfig.HasIndependentMocks = false; System.Assert.areEqual(qm1, qm2); System.Assert.areEqual(qm1, qm3); System.Assert.areEqual(qm1, qm4); fflib_ApexMocksConfig.HasIndependentMocks = true; System.Assert.areNotEqual(qm1, qm2); System.Assert.areNotEqual(qm1, qm3); System.Assert.areNotEqual(qm1, qm4); System.Assert.areEqual(qm2, qm3); System.Assert.areNotEqual(qm2, qm4); System.Assert.areNotEqual(qm3, qm4); } @isTest private static void hashCodeReturnsExpectedResultsForHasDependentMocks() { //Given String instance = 'My object instance'; String instance2 = 'My other object instance'; fflib_QualifiedMethod qm1 = new fflib_QualifiedMethod('Type1', 'Method1', new List{ Integer.class } ); fflib_QualifiedMethod qm2 = new fflib_QualifiedMethod('Type1', 'Method1', new List{ Integer.class }, instance); fflib_QualifiedMethod qm3 = new fflib_QualifiedMethod('Type1', 'Method1', new List{ Integer.class }, instance); fflib_QualifiedMethod qm4 = new fflib_QualifiedMethod('Type1', 'Method1', new List{ Integer.class }, instance2); //When/thens fflib_ApexMocksConfig.HasIndependentMocks = false; System.Assert.areEqual(qm1.hashCode(), qm2.hashCode()); System.Assert.areEqual(qm1.hashCode(), qm3.hashCode()); System.Assert.areEqual(qm1.hashCode(), qm4.hashCode()); fflib_ApexMocksConfig.HasIndependentMocks = true; System.Assert.areNotEqual(qm1.hashCode(), qm2.hashCode()); System.Assert.areNotEqual(qm1.hashCode(), qm3.hashCode()); System.Assert.areNotEqual(qm1.hashCode(), qm4.hashCode()); System.Assert.areEqual(qm2.hashCode(), qm3.hashCode()); System.Assert.areNotEqual(qm2.hashCode(), qm4.hashCode()); System.Assert.areNotEqual(qm3.hashCode(), qm4.hashCode()); } } ================================================ FILE: sfdx-source/apex-mocks/test/classes/fflib_QualifiedMethodTest.cls-meta.xml ================================================ 63.0 ================================================ FILE: sfdx-source/apex-mocks/test/classes/fflib_SystemTest.cls ================================================ /* * Copyright (c) 2017 FinancialForce.com, inc. All rights reserved. */ @IsTest private class fflib_SystemTest { @IsTest private static void assertEquals_WithNoMatchers_ShouldThrowException() { try { fflib_System.assertEquals('Test String', 'Test String'); System.Assert.fail('Expected exception'); } catch (fflib_ApexMocks.ApexMocksException e) { System.Assert.areEqual('fflib_System.assertEquals expects you to register exactly 1 fflib_IMatcher (typically through the helpers in fflib_Match).', e.getMessage()); } } @IsTest private static void assertEquals_WithTooManyMatchers_ShouldThrowException() { //Register matchers prematurely fflib_Match.stringStartsWith('Test S'); fflib_Match.stringEndsWith('t String'); fflib_Match.stringIsNotBlank(); try { fflib_System.assertEquals(fflib_Match.stringStartsWith('Test S'), 'Test String'); System.Assert.fail('Expected exception'); } catch (fflib_ApexMocks.ApexMocksException e) { System.Assert.areEqual('fflib_System.assertEquals expects you to register exactly 1 fflib_IMatcher (typically through the helpers in fflib_Match).', e.getMessage()); } } @IsTest private static void assertEquals_WithMismatch_ShouldThrowException() { try { fflib_System.assertEquals(fflib_Match.stringStartsWith('Test X'), 'Test String'); System.Assert.fail('Expected exception'); } catch (fflib_ApexMocks.ApexMocksException e) { String expected = 'Actual: Test String'; String actual = e.getMessage(); System.Assert.isTrue(actual.contains(expected), 'Expected: ' + expected + ', Actual: ' + actual); } } @IsTest private static void assertEquals_WithMatch_ShouldPass() { fflib_System.assertEquals(fflib_Match.stringStartsWith('Test S'), 'Test String'); } @IsTest private static void assertEquals_WithCombinedMatcher_ShouldPass() { fflib_System.assertEquals(fflib_Match.allOf( fflib_Match.stringStartsWith('Test S'), fflib_Match.stringEndsWith('t String'), fflib_Match.stringIsNotBlank()) , 'Test String'); } @IsTest private static void assertEquals_WithCustomMessage_WithNoMatchers_ShouldThrowException() { try { fflib_System.assertEquals('Test String', 'Test String', 'My Custom Message'); System.Assert.fail('Expected exception'); } catch (fflib_ApexMocks.ApexMocksException e) { System.Assert.areEqual('fflib_System.assertEquals expects you to register exactly 1 fflib_IMatcher (typically through the helpers in fflib_Match).', e.getMessage()); } } @IsTest private static void assertEquals_WithCustomMessage_WithTooManyMatchers_ShouldThrowException() { //Register matchers prematurely fflib_Match.stringStartsWith('Test S'); fflib_Match.stringEndsWith('t String'); fflib_Match.stringIsNotBlank(); try { fflib_System.assertEquals(fflib_Match.stringStartsWith('Test S'), 'Test String', 'My Custom Message'); System.Assert.fail('Expected exception'); } catch (fflib_ApexMocks.ApexMocksException e) { System.Assert.areEqual('fflib_System.assertEquals expects you to register exactly 1 fflib_IMatcher (typically through the helpers in fflib_Match).', e.getMessage()); } } @IsTest private static void assertEquals_WithCustomMessage_WithMismatch_ShouldThrowException() { try { fflib_System.assertEquals(fflib_Match.stringStartsWith('Test X'), 'Test String', 'My Custom Message'); System.Assert.fail('Expected exception'); } catch (fflib_ApexMocks.ApexMocksException e) { String expected = 'Actual: Test String -- My Custom Message'; String actual = e.getMessage(); System.Assert.isTrue(actual.contains(expected), 'Expected: ' + expected + ', Actual: ' + actual); } } @IsTest private static void assertEquals_WithCustomMessage_WithMatch_ShouldPass() { fflib_System.assertEquals(fflib_Match.stringStartsWith('Test S'), 'Test String', 'My Custom Message'); } @IsTest private static void assertEquals_WithCustomMessage_WithCombinedMatcher_ShouldPass() { fflib_System.assertEquals(fflib_Match.allOf( fflib_Match.stringStartsWith('Test S'), fflib_Match.stringEndsWith('t String'), fflib_Match.stringIsNotBlank()) , 'Test String', 'My Custom Message'); } } ================================================ FILE: sfdx-source/apex-mocks/test/classes/fflib_SystemTest.cls-meta.xml ================================================ 63.0 Active