0

My production code goes like this below:

try{
    insert githhubUsersToInsert;
} catch (DmlException e){
  throw new GithubUsersException('create record failed.');
}

The unit test report tells that the catch block is not entered (3rd and 4th lines), but I am so sure my tests covers this exception, thus I made one more test to add a System.Debug to indicate the catch block is entered;

try{
    insert githhubUsersToInsert;
} catch (DmlException e){
  System.Debug('>>>> DMLException entered');
  throw new GithubUsersException('create record failed.');
}

Now, report says 4th line (System.Debug one) is covered, while the other 2 lines (above and below it) are not.

How is this possible?

==== full code version ====

The full code version is here in github: https://github.com/Xixiao007/soc-demo/commit/18b0d9e20dfc24b63efb5a3dc83c4b346706b46d

This is the DX command result:

❯ sfdx force:apex:test:run -cy -l RunAllTestsInOrg -w 5 -r human
=== Apex Code Coverage
ID                  NAME                  % COVERED  UNCOVERED LINES
──────────────────  ────────────────────  ─────────  ───────────────
01p3E000001czhEQAQ  GithubUserService     100%
01p3E000001czhFQAQ  GithubUsers           89%        9,11
01p3E000001czhIQAQ  RemoteService         100%
01p3E000001czhHQAQ  JSONParser            100%
01p3E000001d1C5QAI  TestData              100%
01p3E000001czhDQAQ  GithubUserController  100%
01p3E000001czhGQAQ  GithubUsersSelector   100%

=== Test Results
TEST NAME                                                               OUTCOME  MESSAGE  RUNTIME (MS)
──────────────────────────────────────────────────────────────────────  ───────  ───────  ────────────
GithubUserControllerTest.whenLocalAlreadyExistThenCreateUserFail        Pass              175
GithubUserControllerTest.whenRemoteExistAndLocalNonExistThenCreateUser  Pass              50
GithubUserControllerTest.whenRemoteNonExistThenCreateUserFail           Pass              23

=== Test Summary
NAME                 VALUE
───────────────────  ───────────────────────────────────────────────
Outcome              Passed
Tests Ran            3
Passing              3
Failing              0
Skipped              0
Pass Rate            100%
Fail Rate            0%
Test Start Time      Dec 27, 2018 6:36 PM
Test Execution Time  248 ms
Test Total Time      248 ms
Command Time         4545 ms
Hostname             https://data-power-907.cs82.my.salesforce.com/
Org Id               00D3E000000DCMIUA4
Username             test-7qg97nwljedl@example.com
Test Run Id          7073E000011TZqc
User Id              0053E000002tkJdQAI
Test Run Coverage    96%
Org Wide Coverage    96%
3

System.debug lines are not covered, and do not count towards code coverage. It should be white in the developer console, not red or blue. For all intents, debug statements are counted as comments. If both the try and catch blocks are not covered, then you never reached the DML statement.

4

It turns out that I missed the HTTP CallOut mocking at the begin of the unit test, thus the unit test throws exception HTTPCallOut is not possible from unit test.

My code in other layer catches all types of exceptions and throw new auraHandleException, which gave me the wrong assumption that the source is DMLexception that I expected.

The solution is to add the HTTP Callout mocking and the code coverage goes to 100%.

Here I list down something learned from this post:

  1. System.Debug will always show as green in code coverage report. Do not assume the code block is entered by its indication.
  2. It often helps to write an assert against an exception message as well as having caught it.
  3. Re-thrown exception might root from different source, including exceptions from the platform (in my case, HTTPCallOut is not possible from unit test).
  4. Instead of using Anonymous Apex to reproduce the issue coming from a unit test, run the unit test and check the debug log of it. These two things could differ.
  5. step 3 above is worthwhile mentioning 3 times!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.