Test for Apex class that creates a custom field

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;







up vote
1
down vote

favorite












I have an apex class that creates a custom field on an sObject via an HttpRequest and I'm not sure how to write a test for this because one of the things I need to test is that the field has the correct value, so a mock or a bypass won't work. I can't get enough code coverage for this class if I exclude the web service call. Not sure where to go with this.



This is the request portion of the class in question:



public class RollupFieldCreator {

@future(callout=true)
public static void createRollupField(String fieldName, String description) {
String fieldApiName = fieldName.trim().toLowerCase().replace(' ', '_') + '__c';

if (!Schema.SObjectType.Asset.fields.getMap().keySet().contains(fieldApiName))
String objectApiName = 'Asset';
String toolingApiEndpoint = '/services/data/v41.0/tooling/sobjects/CustomField/';

HttpRequest createField = new HttpRequest();
createField.setHeader('Authorization', 'Bearer ' + UserInfo.getSessionId());
createField.setHeader('Content-Type', 'application/json');
createField.setEndpoint(URL.getSalesforceBaseUrl().toExternalForm() + toolingApiEndpoint);
createField.setMethod('POST');
String fieldDef = '"Metadata" : '
+ '"type" : "Text", "description" : "' + description
+ '", "inlineHelpText" : "", "precision" : null, "label" : "' + fieldName
+ '", "length" : 255, "required" : false, '
+ '"FullName" : "' + objectApiName + '.' + fieldApiName + '"';
createField.setBody(fieldDef);
Http httpInstance = new Http();
HttpResponse response = httpInstance.send(createField);
System.debug(response);










share|improve this question



















  • 1




    You cannot use tooling API in live/prod to create/alter metadata in live org, That being said you cannot create new fields in test environment, I wonder you have to bypass it using test.isRunningTests.
    – Pranay Jaiswal
    1 hour ago






  • 1




    How are AppExchange packages able to create new fields then?
    – nicolevy
    1 hour ago






  • 1




    The dont create fields via APEX, they package their fields. If you really wanna create a field in Apex there is an ugly to hack to create a Metadata package and then hit deployment endpoint to get it validated and deployed. eg. github.com/afawcett/declarative-lookup-rollup-summaries . I wont advise going that way.
    – Pranay Jaiswal
    1 hour ago











  • There are packages that allow you to create custom fields on objects. This is one: appexchange.salesforce.com/… I am creating a metadata package to create the field currently. I'm not sure how to get enough coverage in the test now, though.
    – nicolevy
    1 hour ago











  • Aint i just said the same thing a comment above? SRC: salesforce.stackexchange.com/q/32016/19118
    – Pranay Jaiswal
    1 hour ago

















up vote
1
down vote

favorite












I have an apex class that creates a custom field on an sObject via an HttpRequest and I'm not sure how to write a test for this because one of the things I need to test is that the field has the correct value, so a mock or a bypass won't work. I can't get enough code coverage for this class if I exclude the web service call. Not sure where to go with this.



This is the request portion of the class in question:



public class RollupFieldCreator {

@future(callout=true)
public static void createRollupField(String fieldName, String description) {
String fieldApiName = fieldName.trim().toLowerCase().replace(' ', '_') + '__c';

if (!Schema.SObjectType.Asset.fields.getMap().keySet().contains(fieldApiName))
String objectApiName = 'Asset';
String toolingApiEndpoint = '/services/data/v41.0/tooling/sobjects/CustomField/';

HttpRequest createField = new HttpRequest();
createField.setHeader('Authorization', 'Bearer ' + UserInfo.getSessionId());
createField.setHeader('Content-Type', 'application/json');
createField.setEndpoint(URL.getSalesforceBaseUrl().toExternalForm() + toolingApiEndpoint);
createField.setMethod('POST');
String fieldDef = '"Metadata" : '
+ '"type" : "Text", "description" : "' + description
+ '", "inlineHelpText" : "", "precision" : null, "label" : "' + fieldName
+ '", "length" : 255, "required" : false, '
+ '"FullName" : "' + objectApiName + '.' + fieldApiName + '"';
createField.setBody(fieldDef);
Http httpInstance = new Http();
HttpResponse response = httpInstance.send(createField);
System.debug(response);










share|improve this question



















  • 1




    You cannot use tooling API in live/prod to create/alter metadata in live org, That being said you cannot create new fields in test environment, I wonder you have to bypass it using test.isRunningTests.
    – Pranay Jaiswal
    1 hour ago






  • 1




    How are AppExchange packages able to create new fields then?
    – nicolevy
    1 hour ago






  • 1




    The dont create fields via APEX, they package their fields. If you really wanna create a field in Apex there is an ugly to hack to create a Metadata package and then hit deployment endpoint to get it validated and deployed. eg. github.com/afawcett/declarative-lookup-rollup-summaries . I wont advise going that way.
    – Pranay Jaiswal
    1 hour ago











  • There are packages that allow you to create custom fields on objects. This is one: appexchange.salesforce.com/… I am creating a metadata package to create the field currently. I'm not sure how to get enough coverage in the test now, though.
    – nicolevy
    1 hour ago











  • Aint i just said the same thing a comment above? SRC: salesforce.stackexchange.com/q/32016/19118
    – Pranay Jaiswal
    1 hour ago













up vote
1
down vote

favorite









up vote
1
down vote

favorite











I have an apex class that creates a custom field on an sObject via an HttpRequest and I'm not sure how to write a test for this because one of the things I need to test is that the field has the correct value, so a mock or a bypass won't work. I can't get enough code coverage for this class if I exclude the web service call. Not sure where to go with this.



This is the request portion of the class in question:



public class RollupFieldCreator {

@future(callout=true)
public static void createRollupField(String fieldName, String description) {
String fieldApiName = fieldName.trim().toLowerCase().replace(' ', '_') + '__c';

if (!Schema.SObjectType.Asset.fields.getMap().keySet().contains(fieldApiName))
String objectApiName = 'Asset';
String toolingApiEndpoint = '/services/data/v41.0/tooling/sobjects/CustomField/';

HttpRequest createField = new HttpRequest();
createField.setHeader('Authorization', 'Bearer ' + UserInfo.getSessionId());
createField.setHeader('Content-Type', 'application/json');
createField.setEndpoint(URL.getSalesforceBaseUrl().toExternalForm() + toolingApiEndpoint);
createField.setMethod('POST');
String fieldDef = '"Metadata" : '
+ '"type" : "Text", "description" : "' + description
+ '", "inlineHelpText" : "", "precision" : null, "label" : "' + fieldName
+ '", "length" : 255, "required" : false, '
+ '"FullName" : "' + objectApiName + '.' + fieldApiName + '"';
createField.setBody(fieldDef);
Http httpInstance = new Http();
HttpResponse response = httpInstance.send(createField);
System.debug(response);










share|improve this question















I have an apex class that creates a custom field on an sObject via an HttpRequest and I'm not sure how to write a test for this because one of the things I need to test is that the field has the correct value, so a mock or a bypass won't work. I can't get enough code coverage for this class if I exclude the web service call. Not sure where to go with this.



This is the request portion of the class in question:



public class RollupFieldCreator {

@future(callout=true)
public static void createRollupField(String fieldName, String description) {
String fieldApiName = fieldName.trim().toLowerCase().replace(' ', '_') + '__c';

if (!Schema.SObjectType.Asset.fields.getMap().keySet().contains(fieldApiName))
String objectApiName = 'Asset';
String toolingApiEndpoint = '/services/data/v41.0/tooling/sobjects/CustomField/';

HttpRequest createField = new HttpRequest();
createField.setHeader('Authorization', 'Bearer ' + UserInfo.getSessionId());
createField.setHeader('Content-Type', 'application/json');
createField.setEndpoint(URL.getSalesforceBaseUrl().toExternalForm() + toolingApiEndpoint);
createField.setMethod('POST');
String fieldDef = '"Metadata" : '
+ '"type" : "Text", "description" : "' + description
+ '", "inlineHelpText" : "", "precision" : null, "label" : "' + fieldName
+ '", "length" : 255, "required" : false, '
+ '"FullName" : "' + objectApiName + '.' + fieldApiName + '"';
createField.setBody(fieldDef);
Http httpInstance = new Http();
HttpResponse response = httpInstance.send(createField);
System.debug(response);







apex webservices code-coverage






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 1 hour ago

























asked 1 hour ago









nicolevy

157




157







  • 1




    You cannot use tooling API in live/prod to create/alter metadata in live org, That being said you cannot create new fields in test environment, I wonder you have to bypass it using test.isRunningTests.
    – Pranay Jaiswal
    1 hour ago






  • 1




    How are AppExchange packages able to create new fields then?
    – nicolevy
    1 hour ago






  • 1




    The dont create fields via APEX, they package their fields. If you really wanna create a field in Apex there is an ugly to hack to create a Metadata package and then hit deployment endpoint to get it validated and deployed. eg. github.com/afawcett/declarative-lookup-rollup-summaries . I wont advise going that way.
    – Pranay Jaiswal
    1 hour ago











  • There are packages that allow you to create custom fields on objects. This is one: appexchange.salesforce.com/… I am creating a metadata package to create the field currently. I'm not sure how to get enough coverage in the test now, though.
    – nicolevy
    1 hour ago











  • Aint i just said the same thing a comment above? SRC: salesforce.stackexchange.com/q/32016/19118
    – Pranay Jaiswal
    1 hour ago













  • 1




    You cannot use tooling API in live/prod to create/alter metadata in live org, That being said you cannot create new fields in test environment, I wonder you have to bypass it using test.isRunningTests.
    – Pranay Jaiswal
    1 hour ago






  • 1




    How are AppExchange packages able to create new fields then?
    – nicolevy
    1 hour ago






  • 1




    The dont create fields via APEX, they package their fields. If you really wanna create a field in Apex there is an ugly to hack to create a Metadata package and then hit deployment endpoint to get it validated and deployed. eg. github.com/afawcett/declarative-lookup-rollup-summaries . I wont advise going that way.
    – Pranay Jaiswal
    1 hour ago











  • There are packages that allow you to create custom fields on objects. This is one: appexchange.salesforce.com/… I am creating a metadata package to create the field currently. I'm not sure how to get enough coverage in the test now, though.
    – nicolevy
    1 hour ago











  • Aint i just said the same thing a comment above? SRC: salesforce.stackexchange.com/q/32016/19118
    – Pranay Jaiswal
    1 hour ago








1




1




You cannot use tooling API in live/prod to create/alter metadata in live org, That being said you cannot create new fields in test environment, I wonder you have to bypass it using test.isRunningTests.
– Pranay Jaiswal
1 hour ago




You cannot use tooling API in live/prod to create/alter metadata in live org, That being said you cannot create new fields in test environment, I wonder you have to bypass it using test.isRunningTests.
– Pranay Jaiswal
1 hour ago




1




1




How are AppExchange packages able to create new fields then?
– nicolevy
1 hour ago




How are AppExchange packages able to create new fields then?
– nicolevy
1 hour ago




1




1




The dont create fields via APEX, they package their fields. If you really wanna create a field in Apex there is an ugly to hack to create a Metadata package and then hit deployment endpoint to get it validated and deployed. eg. github.com/afawcett/declarative-lookup-rollup-summaries . I wont advise going that way.
– Pranay Jaiswal
1 hour ago





The dont create fields via APEX, they package their fields. If you really wanna create a field in Apex there is an ugly to hack to create a Metadata package and then hit deployment endpoint to get it validated and deployed. eg. github.com/afawcett/declarative-lookup-rollup-summaries . I wont advise going that way.
– Pranay Jaiswal
1 hour ago













There are packages that allow you to create custom fields on objects. This is one: appexchange.salesforce.com/… I am creating a metadata package to create the field currently. I'm not sure how to get enough coverage in the test now, though.
– nicolevy
1 hour ago





There are packages that allow you to create custom fields on objects. This is one: appexchange.salesforce.com/… I am creating a metadata package to create the field currently. I'm not sure how to get enough coverage in the test now, though.
– nicolevy
1 hour ago













Aint i just said the same thing a comment above? SRC: salesforce.stackexchange.com/q/32016/19118
– Pranay Jaiswal
1 hour ago





Aint i just said the same thing a comment above? SRC: salesforce.stackexchange.com/q/32016/19118
– Pranay Jaiswal
1 hour ago











3 Answers
3






active

oldest

votes

















up vote
4
down vote



accepted










AppExchange apps that modify production (e.g. deploying new fields or code) use the Metadata API, not the Tooling API. The Tooling API is intended for development purposes. You will need to write your code in a way that uses the Metadata API instead. You can see the source code for Rollup Helper to see how it is done in Apex Code; this package also demonstrates code coverage as well for such an app.






share|improve this answer




















  • There are something you can create via Tooling directly in Production, interestingly enough. Not sure if it's a good thing to actually use them in Production though.
    – Charles T
    20 mins ago

















up vote
2
down vote













The normal way to add fields is to include the new field in the new managed package version. (The same also applies where e.g. the Ant deploy task is used.) Typically multiple other components will change at the same time:



  • Apex code if the new field is important to the Apex logic of the managed package

  • Object layouts

  • Any profiles or permission sets also in the package

Making all these changes via the Metadata API would be painful and a new install will update everything fully automatically.



Things are not so good for version upgrades though as layouts will not automatically change as they are assumed to have perhaps been locally manually edited. But in real upgrades, typically locally created layouts and profiles or permission sets will be in use. Manual instructions are normally provided so customers can edit those as only the customer will know their exact use and whether or not to include the new field. In general, upgrades are a painful area that can't be fully handled by automation. So I suggest to not try (or find some magical 3rd party product that handles all the problems).






share|improve this answer



























    up vote
    1
    down vote













    To answer more directly the question of how you unit test this, the answer is that you can use mocks and the Stub API.



    You say: I can't get enough code coverage for this class if I exclude the web service call.



    And also you say: one of the things I need to test is that the field has the correct value, so a mock or a bypass won't work



    The thing is, you can't actually test the end-to-end behaviour because your unit tests cannot modify the org itself. So you can only assert against the things that are allowed to happen in unit tests.



    The method you have pasted here can totally work with a mock, no problem. You can't test that it actually created the metadata of course. But suppose you decompose this @future method into a non-future method that returns whether the HTTP request was successful, and a future method that calls it. Now you can get coverage on the non-future method and assert it returned the right value (provided by your mock class), and you can get coverage on the one-line future method even though there's nothing to assert.



    If you have code that you absolutely cannot cover unless it can definitively tell you that a field was created, then what you'd need to do is outsource the question of whether the field exists to a helper class. Then use the Stub API to inject a mock of that class into the class you're trying to cover, so when it checks if the new field exists (it doesn't), it gets a fake yes back.





    share






















      Your Answer







      StackExchange.ready(function()
      var channelOptions =
      tags: "".split(" "),
      id: "459"
      ;
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function()
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled)
      StackExchange.using("snippets", function()
      createEditor();
      );

      else
      createEditor();

      );

      function createEditor()
      StackExchange.prepareEditor(
      heartbeatType: 'answer',
      convertImagesToLinks: false,
      noModals: false,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: null,
      bindNavPrevention: true,
      postfix: "",
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      );



      );













       

      draft saved


      draft discarded


















      StackExchange.ready(
      function ()
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fsalesforce.stackexchange.com%2fquestions%2f233304%2ftest-for-apex-class-that-creates-a-custom-field%23new-answer', 'question_page');

      );

      Post as a guest






























      3 Answers
      3






      active

      oldest

      votes








      3 Answers
      3






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes








      up vote
      4
      down vote



      accepted










      AppExchange apps that modify production (e.g. deploying new fields or code) use the Metadata API, not the Tooling API. The Tooling API is intended for development purposes. You will need to write your code in a way that uses the Metadata API instead. You can see the source code for Rollup Helper to see how it is done in Apex Code; this package also demonstrates code coverage as well for such an app.






      share|improve this answer




















      • There are something you can create via Tooling directly in Production, interestingly enough. Not sure if it's a good thing to actually use them in Production though.
        – Charles T
        20 mins ago














      up vote
      4
      down vote



      accepted










      AppExchange apps that modify production (e.g. deploying new fields or code) use the Metadata API, not the Tooling API. The Tooling API is intended for development purposes. You will need to write your code in a way that uses the Metadata API instead. You can see the source code for Rollup Helper to see how it is done in Apex Code; this package also demonstrates code coverage as well for such an app.






      share|improve this answer




















      • There are something you can create via Tooling directly in Production, interestingly enough. Not sure if it's a good thing to actually use them in Production though.
        – Charles T
        20 mins ago












      up vote
      4
      down vote



      accepted







      up vote
      4
      down vote



      accepted






      AppExchange apps that modify production (e.g. deploying new fields or code) use the Metadata API, not the Tooling API. The Tooling API is intended for development purposes. You will need to write your code in a way that uses the Metadata API instead. You can see the source code for Rollup Helper to see how it is done in Apex Code; this package also demonstrates code coverage as well for such an app.






      share|improve this answer












      AppExchange apps that modify production (e.g. deploying new fields or code) use the Metadata API, not the Tooling API. The Tooling API is intended for development purposes. You will need to write your code in a way that uses the Metadata API instead. You can see the source code for Rollup Helper to see how it is done in Apex Code; this package also demonstrates code coverage as well for such an app.







      share|improve this answer












      share|improve this answer



      share|improve this answer










      answered 1 hour ago









      sfdcfox

      228k10176390




      228k10176390











      • There are something you can create via Tooling directly in Production, interestingly enough. Not sure if it's a good thing to actually use them in Production though.
        – Charles T
        20 mins ago
















      • There are something you can create via Tooling directly in Production, interestingly enough. Not sure if it's a good thing to actually use them in Production though.
        – Charles T
        20 mins ago















      There are something you can create via Tooling directly in Production, interestingly enough. Not sure if it's a good thing to actually use them in Production though.
      – Charles T
      20 mins ago




      There are something you can create via Tooling directly in Production, interestingly enough. Not sure if it's a good thing to actually use them in Production though.
      – Charles T
      20 mins ago












      up vote
      2
      down vote













      The normal way to add fields is to include the new field in the new managed package version. (The same also applies where e.g. the Ant deploy task is used.) Typically multiple other components will change at the same time:



      • Apex code if the new field is important to the Apex logic of the managed package

      • Object layouts

      • Any profiles or permission sets also in the package

      Making all these changes via the Metadata API would be painful and a new install will update everything fully automatically.



      Things are not so good for version upgrades though as layouts will not automatically change as they are assumed to have perhaps been locally manually edited. But in real upgrades, typically locally created layouts and profiles or permission sets will be in use. Manual instructions are normally provided so customers can edit those as only the customer will know their exact use and whether or not to include the new field. In general, upgrades are a painful area that can't be fully handled by automation. So I suggest to not try (or find some magical 3rd party product that handles all the problems).






      share|improve this answer
























        up vote
        2
        down vote













        The normal way to add fields is to include the new field in the new managed package version. (The same also applies where e.g. the Ant deploy task is used.) Typically multiple other components will change at the same time:



        • Apex code if the new field is important to the Apex logic of the managed package

        • Object layouts

        • Any profiles or permission sets also in the package

        Making all these changes via the Metadata API would be painful and a new install will update everything fully automatically.



        Things are not so good for version upgrades though as layouts will not automatically change as they are assumed to have perhaps been locally manually edited. But in real upgrades, typically locally created layouts and profiles or permission sets will be in use. Manual instructions are normally provided so customers can edit those as only the customer will know their exact use and whether or not to include the new field. In general, upgrades are a painful area that can't be fully handled by automation. So I suggest to not try (or find some magical 3rd party product that handles all the problems).






        share|improve this answer






















          up vote
          2
          down vote










          up vote
          2
          down vote









          The normal way to add fields is to include the new field in the new managed package version. (The same also applies where e.g. the Ant deploy task is used.) Typically multiple other components will change at the same time:



          • Apex code if the new field is important to the Apex logic of the managed package

          • Object layouts

          • Any profiles or permission sets also in the package

          Making all these changes via the Metadata API would be painful and a new install will update everything fully automatically.



          Things are not so good for version upgrades though as layouts will not automatically change as they are assumed to have perhaps been locally manually edited. But in real upgrades, typically locally created layouts and profiles or permission sets will be in use. Manual instructions are normally provided so customers can edit those as only the customer will know their exact use and whether or not to include the new field. In general, upgrades are a painful area that can't be fully handled by automation. So I suggest to not try (or find some magical 3rd party product that handles all the problems).






          share|improve this answer












          The normal way to add fields is to include the new field in the new managed package version. (The same also applies where e.g. the Ant deploy task is used.) Typically multiple other components will change at the same time:



          • Apex code if the new field is important to the Apex logic of the managed package

          • Object layouts

          • Any profiles or permission sets also in the package

          Making all these changes via the Metadata API would be painful and a new install will update everything fully automatically.



          Things are not so good for version upgrades though as layouts will not automatically change as they are assumed to have perhaps been locally manually edited. But in real upgrades, typically locally created layouts and profiles or permission sets will be in use. Manual instructions are normally provided so customers can edit those as only the customer will know their exact use and whether or not to include the new field. In general, upgrades are a painful area that can't be fully handled by automation. So I suggest to not try (or find some magical 3rd party product that handles all the problems).







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered 1 hour ago









          Keith C

          91.1k1083188




          91.1k1083188




















              up vote
              1
              down vote













              To answer more directly the question of how you unit test this, the answer is that you can use mocks and the Stub API.



              You say: I can't get enough code coverage for this class if I exclude the web service call.



              And also you say: one of the things I need to test is that the field has the correct value, so a mock or a bypass won't work



              The thing is, you can't actually test the end-to-end behaviour because your unit tests cannot modify the org itself. So you can only assert against the things that are allowed to happen in unit tests.



              The method you have pasted here can totally work with a mock, no problem. You can't test that it actually created the metadata of course. But suppose you decompose this @future method into a non-future method that returns whether the HTTP request was successful, and a future method that calls it. Now you can get coverage on the non-future method and assert it returned the right value (provided by your mock class), and you can get coverage on the one-line future method even though there's nothing to assert.



              If you have code that you absolutely cannot cover unless it can definitively tell you that a field was created, then what you'd need to do is outsource the question of whether the field exists to a helper class. Then use the Stub API to inject a mock of that class into the class you're trying to cover, so when it checks if the new field exists (it doesn't), it gets a fake yes back.





              share


























                up vote
                1
                down vote













                To answer more directly the question of how you unit test this, the answer is that you can use mocks and the Stub API.



                You say: I can't get enough code coverage for this class if I exclude the web service call.



                And also you say: one of the things I need to test is that the field has the correct value, so a mock or a bypass won't work



                The thing is, you can't actually test the end-to-end behaviour because your unit tests cannot modify the org itself. So you can only assert against the things that are allowed to happen in unit tests.



                The method you have pasted here can totally work with a mock, no problem. You can't test that it actually created the metadata of course. But suppose you decompose this @future method into a non-future method that returns whether the HTTP request was successful, and a future method that calls it. Now you can get coverage on the non-future method and assert it returned the right value (provided by your mock class), and you can get coverage on the one-line future method even though there's nothing to assert.



                If you have code that you absolutely cannot cover unless it can definitively tell you that a field was created, then what you'd need to do is outsource the question of whether the field exists to a helper class. Then use the Stub API to inject a mock of that class into the class you're trying to cover, so when it checks if the new field exists (it doesn't), it gets a fake yes back.





                share
























                  up vote
                  1
                  down vote










                  up vote
                  1
                  down vote









                  To answer more directly the question of how you unit test this, the answer is that you can use mocks and the Stub API.



                  You say: I can't get enough code coverage for this class if I exclude the web service call.



                  And also you say: one of the things I need to test is that the field has the correct value, so a mock or a bypass won't work



                  The thing is, you can't actually test the end-to-end behaviour because your unit tests cannot modify the org itself. So you can only assert against the things that are allowed to happen in unit tests.



                  The method you have pasted here can totally work with a mock, no problem. You can't test that it actually created the metadata of course. But suppose you decompose this @future method into a non-future method that returns whether the HTTP request was successful, and a future method that calls it. Now you can get coverage on the non-future method and assert it returned the right value (provided by your mock class), and you can get coverage on the one-line future method even though there's nothing to assert.



                  If you have code that you absolutely cannot cover unless it can definitively tell you that a field was created, then what you'd need to do is outsource the question of whether the field exists to a helper class. Then use the Stub API to inject a mock of that class into the class you're trying to cover, so when it checks if the new field exists (it doesn't), it gets a fake yes back.





                  share














                  To answer more directly the question of how you unit test this, the answer is that you can use mocks and the Stub API.



                  You say: I can't get enough code coverage for this class if I exclude the web service call.



                  And also you say: one of the things I need to test is that the field has the correct value, so a mock or a bypass won't work



                  The thing is, you can't actually test the end-to-end behaviour because your unit tests cannot modify the org itself. So you can only assert against the things that are allowed to happen in unit tests.



                  The method you have pasted here can totally work with a mock, no problem. You can't test that it actually created the metadata of course. But suppose you decompose this @future method into a non-future method that returns whether the HTTP request was successful, and a future method that calls it. Now you can get coverage on the non-future method and assert it returned the right value (provided by your mock class), and you can get coverage on the one-line future method even though there's nothing to assert.



                  If you have code that you absolutely cannot cover unless it can definitively tell you that a field was created, then what you'd need to do is outsource the question of whether the field exists to a helper class. Then use the Stub API to inject a mock of that class into the class you're trying to cover, so when it checks if the new field exists (it doesn't), it gets a fake yes back.






                  share













                  share


                  share








                  edited 46 secs ago

























                  answered 7 mins ago









                  Charles T

                  5,3751518




                  5,3751518



























                       

                      draft saved


                      draft discarded















































                       


                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function ()
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fsalesforce.stackexchange.com%2fquestions%2f233304%2ftest-for-apex-class-that-creates-a-custom-field%23new-answer', 'question_page');

                      );

                      Post as a guest













































































                      Comments

                      Popular posts from this blog

                      Long meetings (6-7 hours a day): Being “babysat” by supervisor

                      What does second last employer means? [closed]

                      One-line joke