Advanced 18 min read

Apex Tests for Controllers and Services

By the end of this lesson, you'll be able to:

  • Explain why Apex requires its own separate test coverage from Jest tests
  • Write a basic Apex test class using Test.startTest()/stopTest()
  • Test an Apex controller method that an LWC component depends on

Prerequisites: "Testing Wire Adapters and Apex-Dependent Components"

Why Apex Needs Its Own Tests

Salesforce requires a minimum percentage of Apex code coverage by tests before code can be deployed to production — a genuine platform requirement, entirely separate from Jest. Jest tests (Lessons 1-3) verify a component's own client-side rendering and interaction logic; they provide zero coverage toward this Apex requirement, since they never actually execute real Apex code.

Anatomy of an Apex Test Class

@isTest
private class AccountSearchControllerTest {
    @isTest
    static void testSearchReturnsMatchingAccounts() {
        Account testAccount = new Account(Name = 'Acme Corp');
        insert testAccount;

        Test.startTest();
        List<AccountResult> results = AccountSearchController.search('Acme');
        Test.stopTest();

        System.assertEquals(1, results.size(), 'Expected exactly one matching account');
        System.assertEquals('Acme Corp', results[0].accountName, 'Account name should match');
    }
}

@isTest marks both the class and each test method. Test.startTest()/Test.stopTest() reset governor limits (Module 7) partway through the test, letting the code under test run with a fresh set of limits, isolated from setup work done beforehand. System.assertEquals(expected, actual, message) is the core assertion pattern — a clear failure message matters just as much here as in Jest.

Testing a Controller Exposed to LWC

The test above exercises AccountSearchController.search (Module 7's project) exactly as the component's @wire call would — inserting real test data, calling the method, and asserting the shape and content of what comes back, including that the wrapper class's fields (Module 7) are populated correctly.

Why Both Matter

Neither testing layer substitutes for the other. Jest verifies the component genuinely renders and behaves correctly given some data; Apex tests verify the server-side logic genuinely returns correct, secure data — and only Apex tests satisfy the platform's actual deployment coverage requirement. A fully tested feature needs both.

Exercise

Write an Apex test asserting that AccountSearchController.search returns an empty list when no Accounts match the search term.

Show hint

Insert an Account with a different name, then search for something that shouldn't match.

APEX

Exercise

Challenge: explain, as a comment, why a component with 100% Jest test coverage can still fail to deploy to a production org.

Show hint

Think about what Jest coverage does and doesn't measure.

APEX

Apex Tests for Controllers and Services Quiz

1. What does Jest test coverage contribute toward Salesforce's Apex code coverage requirement?

2. What does @isTest mark in an Apex test class?

3. What does Test.startTest()/Test.stopTest() do?

4. What is required for Apex code to be deployed to a production org?

5. Why do both Jest tests and Apex tests matter for a fully tested feature?

Log in to submit the quiz and save your score.

My Notes

Log in to keep private notes on this lesson.

Questions about this lesson

No questions yet — be the first to ask.

Log in to ask a question about this lesson.

Summary

Apex test coverage is a genuine platform deployment requirement, entirely separate from Jest — the two testing layers are complementary, each verifying a different half of the LWC/Apex boundary.