Apex Test Active Case Assignment Rules Assertion Fails

If you are testing active assignment rules you need to add it as an DMLOptions during testing else your assignment rule(s) will not get called and your assertion(s) may fail.

If you have one active Case Assignment Rule you can use dmlOpts.assignmentRuleHeader.useDefaultRule = true else you need to query for AssignmentRules. To query AssignmentRules you will need to have without sharing set as your class level access, else you will not get access to AssignmentRules.

If you have one method to insertCases you can make sure your assignmentRules run every time you execute a test class.

  public Id insertCase(Case bpCase){
      fflib_ISObjectUnitOfWork uow = Rest_App.UnitOfWork.newInstance();

      if (Test.isRunningTest()){
        Database.DMLOptions dmlOpts = new Database.DMLOptions();
         dmlOpts.assignmentRuleHeader.useDefaultRule = true;
         bpCase.SetOptions(dmlOpts);
      }

      uow.registerNew(bpCase);
      uow.commitWork();
      return bpCase.Id;
}

Here is the actual test class:

	@isTest(SeeAllData=true) static void testClientRequest(){
		RestRequest req = new RestRequest();
		RestResponse res = new RestResponse();
		Map<String, String> mapOfIds = App_Global_Test.setupCommunityUserReturnIds();

		test.startTest();
			System.runAs(new User(Id=mapOfIds.get('UserId'))){
				req.requestBody = Blob.valueOf('{"contactId":"'+mapOfIds.get('ContactId')+'", "type":"Client Request", "description":"Please help me with my account", "subject":"Client Request", "reason":"Client Request", "origin":"App"}');
				req.requestURI = '/v1/support/case';
				req.httpMethod = 'POST';
				RestContext.request = req;
				RestContext.response = res;

				App_Rest_Dispatcher.doPost();
				System.assert(res.responseBody!=null);
				System.assertEquals(res.statusCode, 200);
		 }
		test.stopTest();

		List<Case> supportCase = [Select Id, Subject, Description, Type, Owner.Name from Case where ContactId=:mapOfIds.get('ContactId')];
		System.assertEquals(supportCase.size(), 1);
		System.assertEquals(supportCase.get(0).Subject, 'Client Request');
		System.assertEquals(supportCase.get(0).Type, 'Client Request');
		System.assertEquals(supportCase.get(0).Owner.Name, 'Client Services Queue');
	}

Heroku MemCached Junit Test

Heroku Memcached Cloud Junit Test

package com.example.cache;

import static org.junit.Assert.*;

import java.io.IOException;
import java.math.BigInteger;

import net.spy.memcached.AddrUtil;
import net.spy.memcached.ConnectionFactoryBuilder;
import net.spy.memcached.MemcachedClient;
import net.spy.memcached.auth.AuthDescriptor;
import net.spy.memcached.auth.PlainCallbackHandler;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.example.model.Customer;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class CacheCustomerServiceTest {
	
	private static final String USERNAME="######";
	private static final String PASSWORD="######";
	private static final String HOST="######";
	
	@Configuration
	static class ContextConfiguration{
		
		@Bean
		public MemcachedClient memcachedConfig() {
		try{
			 AuthDescriptor ad = new AuthDescriptor(new String[] { "PLAIN" },
				        new PlainCallbackHandler(USERNAME, PASSWORD));

			MemcachedClient mc = new MemcachedClient(
					new ConnectionFactoryBuilder()
				                  .setProtocol(ConnectionFactoryBuilder.Protocol.BINARY)
				                  .setAuthDescriptor(ad).build(),
		    AddrUtil.getAddresses(HOST));
			return mc;
		} catch (IOException ex) {}
			return null;
		}
	}
	
	@Autowired MemcachedClient memcachedConfig;
	
	@Test
	public void testMemCachedSet() {
		memcachedConfig.set("customerKey", 3600, new Customer(new BigInteger("1"), "John", "Doe"));
		Object value = memcachedConfig.get("customerKey");
		System.out.println(value);
	}
}

JUnit Test Spring MVC Web Services

Spring MVC REST Controller

package com.example.controller.api;

import java.math.BigInteger;
import java.util.Collection;
import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.example.model.CustomerActivity;
import com.example.service.CustomerActivityRepository;
import com.wordnik.swagger.annotations.Api;
import com.wordnik.swagger.annotations.ApiError;
import com.wordnik.swagger.annotations.ApiErrors;
import com.wordnik.swagger.annotations.ApiOperation;
import com.wordnik.swagger.annotations.ApiParam;

@Controller
@RequestMapping(value = "/api/v1/customeractivity")
@Api(value = "Customer operations", listingClass = "CustomerController", basePath = "/api/v1/customeractivity", description = "All operations for customers activity")
public class CustomerActivityController {
	
	@Autowired
	@Qualifier("mongoRepository")
	private CustomerActivityRepository customerService;
	
	 @ApiOperation(value = "Find customer by Id", notes = "Get customer by specifying Id", httpMethod = "GET", responseClass = "Customer", multiValueResponse = true)
	 @ApiErrors(value = { @ApiError(code = 400, reason = "Invalid ID supplied"), @ApiError(code = 404, reason = "Customer not found") })
	 @RequestMapping(value = "/find/{customerId}", method = RequestMethod.GET, produces = "application/json")
	 public @ResponseBody List<CustomerActivity> findCustomerById(@ApiParam(internalDescription = "java.lang.string", name = "customerId", required = true, value = "string") @PathVariable String customerId) {
		 	List<CustomerActivity> customer = customerService.findCustomerActivityByCustomerId(customerId);
	        return customer;
	 }
}

Spring MVC REST Junit Test

package com.example.controller.api;

import static org.junit.Assert.*;

import java.util.Arrays;
import java.util.Date;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;

import com.example.model.CustomerActivity;
import com.example.service.CustomerActivityRepositoryImpl;

import static org.mockito.Mockito.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;

@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration(classes={CustomerActivityController.class, CustomerActivityRepositoryImpl.class})
public class CustomerActivityControllerTest {
	
	private MockMvc mockMvc;
	
	@Autowired CustomerActivityController customerActivityController;
	
	@Before
	public void setup() {
		this.mockMvc =  MockMvcBuilders.standaloneSetup(customerActivityController).build();
	}
	
	@Test
	public void testCustomerActivityFindCustomerById() throws Exception {
		CustomerActivity customerActivity = new CustomerActivity("123", "SMS Received", new Date(), "SMS", "Workflow", "http://workflow.com");
		CustomerActivityController mock = org.mockito.Mockito.mock(CustomerActivityController.class);
		when(mock.findCustomerById("123")).thenReturn(Arrays.asList(customerActivity));
		
		this.mockMvc.perform(get("/api/v1/customeractivity/find/123"))
		.andExpect(status().isOk())
		.andExpect(content().contentType("application/json"))
		.andExpect(jsonPath("$[0].customerId").value("123"));
		verifyNoMoreInteractions(mock);
	}
}

Minimize and Optimize Apex Test Classes with SmartFactory

I was writing allot of test code to create SObjects and all the necessary fields. There are some problems when writing test code when specifying all the necessary fields.

Some of the things to consider when creating test fields is required fields and pre-populating lookups. Let us look at some examples:
Let’s start of creating a Account in a Test Class:

Account newAccount = new Account(Name='This is a Test Account');

Now we create the Contact associated to that Account:

Contact newContact = new Contact(AccountId=newAccount.Id);

but Contact has more required fields and will fail if I call the:

 insert newContact;

Let’s take it a bit further and create an Opportunity and select the newAccount.

Opportunity newOpportunity = new Opportunity(AccountId=newAccount.Id);

the same story for opportunity is we need more required fields to be completed, and do we always know the required fields?No for some unknown Salesforce orgs this may be a problem.

Let’s see how we can solve the problem of required fields and lookup during sObject creation:

Contact c = (Contact)SmartFactory.createSObject('Contact', true);

The second argument (true) toggles the cascade option, which populates any lookup fields on the object with their own newly created objects. It’s a powerful way to create hierarchies of test data quickly and easily so you can focus on writing test and implementation logic.

Now we can create an Opportunity without specifying an Account or Contact:

Opportunity o = (Opportunity)SmartFactory.createSObject('Opportunity', true);

This will create, a Account, Contact and Opportunity for you in one line.

SmartFactory uses the describe metadata to populate all fields with data of the right type. It currently handles string and lookup fields. For lookup fields, it creates an appropriate object and then uses that object’s ID.

Testing Active/Passive Datapower Cluster

Testing an Active/Passive Datapower Cluster is very easy. Just create exactly the same XML Firewall service on both Datapower A and Datapower B appliances. Specify the front End-Handler IP address as the VIP address created.

Execute the curl command to run the policy where the VIP is the Front Side Handler.  Enable the probes on both devices to make sure that the request and response is successful.  Switch the active appliance (Datapower A) off or reboot and continue to execute the command. You will see that the passive appliance will take over from Datapower A. When Datapower A is rebooted or switched on again it will take over again.