Test Class – Error: Compile Error: Field is not writeable: Opportunity.ConnectionReceivedId

I have a re-parenting trigger that fires if the connectionReceivedId is of a certain value. The sad part is that it looks like that field is not writeable, so testing is not possible. I know I could rewrite the trigger to work around this, but I would enjoy being able to actually sort records needing re-parenting by the connection from which they were received.

@istest
public class reparenttestclass{
static testmethod void reparenttestclassmethod(){

Opportunity testopp = new Opportunity(
name = 'testopp', recordTypeId = 'xxxxxxxxxx', connectionReceivedId = 'testconnid', AccountId = 'xxxxxxxxxxx', CloseDate = Date.newInstance(2009, 3, 11), StageName = 'testopp');
insert testopp;

Account testacct = new Account(
name = 'testacct');
insert testacct;

}}

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

To test things like this, I create a class that mimics the object. During the test I deserialize the class into a list of those objects. In the code that the trigger calls, I check for a static test property to be true and if so then get the test objects instead of database object. It allows you to test the functionality of that piece (sorting, etc) while being able to control the testing of actual database records for other tests.

An example (a bit abstract) of how to deserialize a class to get an sObject that can be used in your code:

Public class parentClassTest{
  public static useTestObject = false;

  public static test method void doTest(){
        useTestObject = true;

        //insert records to cause trigger to fire
  }

  public static Opportunity[] getTestOpps(){
      mytestClass[] tmp = new MyTestClass[]{};
      //populate with records
      return (Opportunity[])json.deserialize(json.serialize(New myTestClass()),List<Opportunity>.class);
  }
public class myTestClass{

    public id id {get;set;}
    public String name {get;set;}
    public Id connectionReceivedId {get;set;}

    public mytestClass(){
        name = 'test';
    }

}

In your code you would:

Opportunity[] o = parentClassTest.useTestObject ? parentTestClass.getTestOpps() : TRIGGERVALUES;

Method 2

Salesforce to Salesforce is notoriously difficult to test in a non-SeeAllData=true style as you can’t successfully mock PartnerNetworkRecordConnection or PartnerNetworkConnection as you might want. This extends to setting values of connectionReceivedId or connectionSentId in Sobjects

An alternate framework solution using interfaces; things can get more complicated if the underlying service class being tested needs access to the PNRC object as well but the approach holds as you can mock up PNRC in JSON.deserialize as @Eric shows as long as you don’t try and actually do DML.

  public interface IS2S {
      ID getConnectionReceivedId(ID id);
  }


  // ---------PROD Service Class--------------------

  public class MyService  {

    private map<ID,SObject> idToSObjectMap;
    public MyService(map<ID,Sobject idToSobjectMap) {this.idToSobjectMap = idToSobjectMap;}

    @TestVisible private IS2S iS2S = new IS2SProd(this); // default interface's concrete impl to PROD version


    public class IS2SProd implements IS2S { // the prod impl of IS2S
         MyService svc;  // addressability to outer class
         public ID getConnectionReceivedID(ID id) { // PROD fetches from real sobject
            return this.svc.idToSObjectMap.get(id).connectionReceivedId;
         }

         public IS2SProd(MyService svc) {this.svc = svc;} // constructor
    }

    public someReturnType doSomething() { // service's worker method
        for (Opportunity o : (Opportunity) idToSObjectMap.values()) {
            // use interface to fetch S2S value
            ID connectionReceivedId = iS2S.getConnectionReceivedId(o.id);  
            // do other stuff
        }
        return appropType;
    }
  }


  // ------------TEST class-----------------------------

  @isTest
  private class MyTestClass {

    public class IS2STest implements IS2S {  / test impl of IS2S, constructor provides what to return
      map<ID,ID> oIdTomockedConnectionReceivedIdMap;

      public ID getConnectionReceivedId(ID id) {
        return this.oIdTomockedConnectionReceivedIdMap.get(id);
      }

      public IS2STest(map<ID,ID> oIdTomockedConnectionReceivedIdMap) {
        this.oIdTomockedConnectionReceivedIdMap = oIdTomockedConnectionReceivedIdMap;
      }
    }


    @isTest
    private static void testFoo() {

        // Mock many Opportunities, save in a map of oIdToMockedOpportunitiesMap    
        // Create a map of mockedOpportunityIdsToMockedConnectionReceivedIds    

        MyService svc = new MyService(oIdToMockedOpportunitiesMap);
        // inject into service the test class' implementation of IS2S
        svc.iS2S = new IS2STest(mockedOpportunityIdsToMockedConnectionReceivedIds); 
        svc.doSomething(); // svc will use the test class concrete impl of IS2S to get connectionReceivedId

    }
  }

There may be typos here


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x