Giter Club home page Giter Club logo

apexmock's Introduction

apexmock

force.com Mock data and fixtures for Apex Unit Tests

ApexMock is a library which can assist in dummy data generation for Apex Unit Tests

This library supports two kinds of testing approaches:

  1. tests working with SFDC DB
  • classes Mock, MockData, MockDataStandard, MockTests, MockUtils
  1. tests not touching SFDC DB and working with Mock Database, see class MockDb
  • MockDb is "in-memory" database which can be used to replace calls to SFDC DB in unit tests

Description below covers Approach 1.
Approach 2 is for more advanced developers and they are expected to figure it out by themselves.

in order to use Mock methods Mock.MOCK_DATA has to be initialised first

	Mock.MOCK_DATA = new MyOrgMockDataSet1();

If Mock.MOCK_DATA is not initialised then by default class named MockData will be used (if existis).

Now you can create some objects

	//create Account and Insert into DB
	//only relevant fields need to be specified, the rest will be taken from MyOrgMockDataSet1
	Account acc1 = (Account)Mock.one('Account', 
					new Map<String, Object>{ 'MyField__c' => 'some-value', 'OtherField__c' => 123}, true); 
	//create account but do not Insert yet
	Account acc2 = (Account)Mock.one('Account', new Map<String, Object>{ 'Name' => 'Acc 2'}, false);
	acc2.MyId__c = '123456';
	Database.insert(acc2);
	...
	//generate and save 2 Opportunities using acc1 and acc2 as their Accounts
	List<Opportunity> opps = Mock.many('Opportunity', 
								new Map<String, Object>{ 'Name' => 'Opp#{COUNTER}', 
								'AccountId' => Id[] {acc1.Id, acc2.Id}}, 2, true); 
	...
	...

	//same as above, but less code, all fields except Accoun.Name are taken from fixtures 
	List<Account> accs = Mock.many('Account', new Map<String, Object>{ 'Name' => 'Acc #{COUNTER}'}, 2, true)

	//using Mock.toIds() so each opportunity will receive its own account Id
	List<Opportunity> opps2 = Mock.many('Opportunity', 
								new Map<String, Object>{ 'Name' => 'Opp#{COUNTER}', 
								'AccountId' => Mock.toIds(accs)}, 2, true); 
	...
	...
	
	//similar to above, but we do not care which Account each Opportunity will be assigned to, 
	//because it is not relevant in our test
	//using Mock.DEPENDS_ON
	Map<String, String> dependsOn = new Map<String, String>{'AccountId' => 'Account', 'My_Related_Object_Ref__c' => 'My_Related_Object__c'};
	List<Opportunity> opps2 = Mock.many('Opportunity', 
								new Map<String, Object>{ 'Name' => 'Opp#{COUNTER}', Mock.DEPENDS_ON => dependsOn}, 2, true); 
								
	//ideally above Mock.DEPENDS_ON should be part of custom data fixture, e.g. in MockData class, but if we need to overwrite Mock.DEPENDS_ON value locally then we can.

Another example, create 3 Contacts using only defined earlier fixtures.
The following single line piece of code will create and save a separate Account for each contact.
See MockDataStandard.CONTACT_VALUES for an example of how DEPENDS_ON is defined.

	List<Contact> opps2 = Mock.many('Contact', 3, true); 

See MockTests.cls for more comprehensive usage examples

Why ApexMock

Two most popular ways to generate test data is

  1. create test data individually for every test like this
		Account acc = new Account (Name = 'Test Acc', BillingStreet = 'Some street', Custom_Field__c = 'some value'...);
		Database.insert(acc);
		Opportunity opp = new Opportunity(AccountId = acc.id, StageName = 'Prospecting', Amount = 100, Some_Field__c = 'value here', ...);
		Database.insert(opp);

Even if in your current test you are only interested in Opportunity.Amount and Account.Custom_field__c, you still have to initialise lots of other fields (e.g. Account.Name) because of validation rules.

  1. In order to minimise repeated code you start writing something like this
		public static Account createTestAccount(String name, String billingStreet, ..., Boolean saveIntoDb) {
			//account initialisation code here
		}

then you use it like so:

		Account acc = MyStaticTestClass.createTestAccount('Some Name', 'Some address', ..., true);

With this approach you have to remember the order of parameters in each createTest[xxx]() method or keep getting back to MyStaticTestClass to check what the order is.

At some point you realise that your test requires 10 Accounts and 20 Opportunities. With approach #1 your test data generation code in each test will be massive, with approach #2 you have to generate at least twice as many createTest[xxx]() methods (one creating single object and 1 creating List of objects).

Later you realise that it would be nice if your static dummy data initialisation code had several very different data sets which you can use to test logic for different business processes (or business units) in your SFDC ORG. i.e. in one case your Contacts must have all standard fields filled in and in Spanish, in the other case you need only LastName and UK PostCode.

How do you solve that?

Will you continue increasing your createTest[xxx]() methods base?
Or will you define different data sets once and then just swap them with one line of code like so:

	Mock.MOCK_DATA = new MyOrgMockDataSet1();
	...
	Mock.MOCK_DATA = new MyOrgMockDataSet2();

apexmock's People

Contributors

neowit avatar jeremyross avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.