{"id":15383804,"url":"https://github.com/jamessimone/apex-dml-mocking","last_synced_at":"2026-01-22T06:38:56.180Z","repository":{"id":40282238,"uuid":"259097288","full_name":"jamessimone/apex-dml-mocking","owner":"jamessimone","description":"DML mocking, CRUD mocking, dependency injection framework for Salesforce.com (SFDC) using Apex","archived":false,"fork":false,"pushed_at":"2024-10-29T17:05:51.000Z","size":1082,"stargazers_count":80,"open_issues_count":0,"forks_count":22,"subscribers_count":6,"default_branch":"main","last_synced_at":"2025-02-02T00:51:16.457Z","etag":null,"topics":["apex","apex-class","apex-framework","apex-test","salesforce","salesforce-apex","salesforce-developers","salesforce-development","salesforcedx","sfdc"],"latest_commit_sha":null,"homepage":null,"language":"Apex","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jamessimone.png","metadata":{"files":{"readme":"Readme.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-04-26T17:55:50.000Z","updated_at":"2024-12-13T09:52:51.000Z","dependencies_parsed_at":"2023-01-27T06:16:19.693Z","dependency_job_id":"99935003-01cf-4202-8390-7bbe206fca34","html_url":"https://github.com/jamessimone/apex-dml-mocking","commit_stats":{"total_commits":65,"total_committers":9,"mean_commits":7.222222222222222,"dds":0.3384615384615385,"last_synced_commit":"20c18d391af93c89b16ab74eb50782f7f1092c54"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jamessimone%2Fapex-dml-mocking","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jamessimone%2Fapex-dml-mocking/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jamessimone%2Fapex-dml-mocking/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jamessimone%2Fapex-dml-mocking/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jamessimone","download_url":"https://codeload.github.com/jamessimone/apex-dml-mocking/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245937916,"owners_count":20696987,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["apex","apex-class","apex-framework","apex-test","salesforce","salesforce-apex","salesforce-developers","salesforce-development","salesforcedx","sfdc"],"created_at":"2024-10-01T14:39:42.461Z","updated_at":"2026-01-22T06:38:56.173Z","avatar_url":"https://github.com/jamessimone.png","language":"Apex","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Apex DML Mocking\n\nWelcome to the SFDX project home for blazing fast Apex unit tests! For your consideration, this is an _example_ of how to implement the full CRUD (Create Read Update Delete) mocking implementation within your own Salesforce orgs. You can find out more information by perusing:\n\n- [force-app](/force-app) for implementation details\n- [example-app](/example-app) for an example Account Handler with mocking set up\n\nWriting tests that scale as the size of your organization grows is an increasingly challenging problem in the Salesforce world. It's not uncommon in large companies for deploys to last several hours; the vast majority of that time is spent running tests to verify that your code coverage is good enough for the deploy to succeed. Tests don't _need_ to take that long.\n\nThis repo shows you how you can mock your SOQL queries and DML statements in Apex by using lightweight wrappers that are dependency injected into your business logic objects. This allows you to replace expensive test setup and test teardown with a fake database. I've used this method to cut testing time down by 90%+ -- in a small org, with only a few hundred tests, running tests and deploying can be done in under five minutes (easily). In large orgs, with many hundreds or thousands of tests, overall testing time tends to scale more linearly with organizational complexity; there are additional optimizations that can be done in these orgs to keep deploys in the 10 minute(s) range.\n\n## Access Level \u0026 DML Option Setting\n\nBoth `IDML` and `IRepository` instances returned by the framework support the method `IDML setOptions(Database.DMLOptions options, System.AccessLevel accessLevel);`. Note that if DML options are not set by default, this framework uses true for the `allOrNone` value when performing DML, as that is consistent with the standard for calling DML operations without specifying that property. Please also note that DML options are not \"expired\" after having been set -- if you are using an instance of `IRepository` or `IDML` and are performing multiple DML operations using that same instance, the DML options that have been set will continue to apply to subsequent operations until `setOptions` is re-called, or a new instance is initialized. DML options are _not_ shared between instances; they are not statically set. Passing `null` for the DML options value will only update the access level.\n\nBy default, all operations are run using `System.AccessMode.SYSTEM_MODE`. You can either override this (for `IDML` and `IRepository` instances) by calling `setOptions`, as shown above, or by calling `IRepository setAccessLevel(System.AccessLevel accessLevel);` on `IRepository` instances. Like DML options, the access level that is set for an instance is then the one used for subsequent operations involving that repository instance.\n\n## DML Mocking Basics\n\nTry checking out the source code for the DML wrapping classes:\n\n- [DML](force-app/dml/DML.cls)\n- [DMLMock](force-app/dml/DMLMock.cls)\n\n## SOQL Mocking Basics\n\nTake a look at the following classes to understand how you can replace raw SOQL in your code with testable (and extendable) strongly typed queries:\n\n- [Repository](force-app/repository/Repository.cls)\n- [Query](force-app/repository/Query.cls)\n\nThen, move on to the more complicated examples:\n\n- [AggregateRepository](force-app/repository/AggregateRepository.cls)\n- [Aggregation](force-app/repository/Aggregation.cls)\n- [AggregateRepositoryTests](force-app/repository/AggregateRepositoryTests.cls) - a good example of how to use the above two classes\n- [FieldLevelHistoryRepo](force-app/repository/FieldLevelHistoryRepo.cls)\n- [FieldLevelHistory](force-app/repository/FieldLevelHistory.cls)\n\nWhile opinionated in implementation, these classes are also just scratching the surface of what's possible when taking advantage of the Factory pattern in combination with the Repository pattern, including full support for:\n\n- strongly typed subqueries (queries returning children records)\n- strongly typed parent-level fields\n- the ability to easily extend classes like `Repository` to include things like limits, order bys, etc ...\n\n## Dependency Injection Basics\n\nThe \"Factory\" pattern is of particular importance for DML mocking, because it allows you to have only _one_ stub in your code for deciding whether or not to use mocks when running tests; crucially, the stub is only available when tests are being run: you cannot mock things in production-grade code.\n\nYou can have as many Factories as you'd like. I like to break my Factories out by responsibility:\n\n- A factory for Trigger handlers\n- A [factory](force-app/factory/Factory.cls) for basic classes\n- The [RepoFactory](force-app/factory/RepoFactory.cls) for CRUD related objects\n\nIt's a pretty standard approach. You might choose to break things down by (business) domain. There's no right way.\n\n## Lazy-Loading Dependencies\n\nThe one (possible) downside to using a big Factory class comes with respect to runtime performance when referencing the factory. This is because the Apex compiler \"spiders\" out, loading type signatures referenced by public methods. While this performance hit is typically negligible, there are some niche use-cases where loading _every_ class reference you need means a performance hit that you can't afford to take. For these cases, consider using the [LazyFactory](force-app/factory/LazyFactory.cls) approach - initializing it directly within your dependencies, and using getters within the `LazyFactory` to reference the dependencies you need. By using getters (see the example in [LazyFactoryTest](force-app/factory/LazyFactoryTest.cls)), you can delay the type-loading and spidering until a dependency is actually used.\n\n## Package-Based Development\n\nThese repository (as of 18 May 2023) has been slightly reworked to provide better support for package-based development. The updates are primarily to show how the `example-app` folder can be in a completely separate package while still allowing for strongly-typed references (and package-specific factories and repo factories) to be referenced properly. For a concrete example, check out:\n\n- [The unit tests in HistoryRepoTests](example-app/history/HistoryRepoTests.cls)\n- [The extended factory](example-app/ExampleFactory.cls)\n- [The extended repo factory](example-app/ExampleRepoFactory.cls)\n\n---\n\n## More Information\n\nFor more information on these patterns and how to use them, consider the free resources I've published under [The Joys Of Apex](https://www.jamessimone.net/blog/joys-of-apex/). Thanks for your time!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjamessimone%2Fapex-dml-mocking","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjamessimone%2Fapex-dml-mocking","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjamessimone%2Fapex-dml-mocking/lists"}