From 0db60a540a3acf3e4efa3ee8f91423f2d4da4fa0 Mon Sep 17 00:00:00 2001 From: Mitch Spano Date: Fri, 30 Jan 2026 14:01:41 -0600 Subject: [PATCH] Standardized test method annotations to `@IsTest` and updated assertion methods to use `System.Assert` class --- .../assets/test_template.apex | 28 ++--- .../apex-test-class/SKILL.md | 14 +-- .../references/assertion-patterns.md | 112 ++++++++++++------ .../references/async-testing.md | 66 +++++------ .../references/mocking-patterns.md | 46 +++---- .../references/test-data-factory.md | 2 +- 6 files changed, 156 insertions(+), 112 deletions(-) diff --git a/skills/apex-development/trigger-refactor-pipeline/assets/test_template.apex b/skills/apex-development/trigger-refactor-pipeline/assets/test_template.apex index d9c02e1..fbed093 100644 --- a/skills/apex-development/trigger-refactor-pipeline/assets/test_template.apex +++ b/skills/apex-development/trigger-refactor-pipeline/assets/test_template.apex @@ -54,7 +54,7 @@ private class [ObjectName]TriggerHandlerTest { // TODO: Add assertions // List inserted = [SELECT Id, Name FROM Opportunity WHERE Name = 'Valid Opp']; - // System.assertEquals(1, inserted.size(), 'Should insert 1 record'); + // System.Assert.areEqual(1, inserted.size(), 'Should insert 1 record'); } /** @@ -82,13 +82,13 @@ private class [ObjectName]TriggerHandlerTest { } catch (DmlException e) { exceptionThrown = true; // TODO: Assert error message - // System.assert(e.getMessage().contains('must have Amount'), + // System.Assert.isTrue(e.getMessage().contains('must have Amount'), // 'Should throw validation error'); } Test.stopTest(); - // System.assert(exceptionThrown, 'Should have thrown an exception'); + // System.Assert.isTrue(exceptionThrown, 'Should have thrown an exception'); } /** @@ -109,7 +109,7 @@ private class [ObjectName]TriggerHandlerTest { // TODO: Add assertions // Opportunity updated = [SELECT Description FROM Opportunity WHERE Id = :testOpps[0].Id]; - // System.assert(updated.Description.contains('Stage changed'), + // System.Assert.isTrue(updated.Description.contains('Stage changed'), // 'Description should be updated'); } @@ -141,7 +141,7 @@ private class [ObjectName]TriggerHandlerTest { // TODO: Query for related records created by handler // List createdTasks = [SELECT Id FROM Task]; - // System.assertEquals(1, createdTasks.size(), 'Should create 1 task'); + // System.Assert.areEqual(1, createdTasks.size(), 'Should create 1 task'); } /** @@ -162,8 +162,8 @@ private class [ObjectName]TriggerHandlerTest { // TODO: Query for side effects (e.g., Tasks created) // List tasks = [SELECT Id, Subject FROM Task WHERE WhatId = :testOpps[0].Id]; - // System.assertEquals(1, tasks.size(), 'Should create 1 task'); - // System.assertEquals('Send thank-you', tasks[0].Subject); + // System.Assert.areEqual(1, tasks.size(), 'Should create 1 task'); + // System.Assert.areEqual('Send thank-you', tasks[0].Subject); } /** @@ -191,7 +191,7 @@ private class [ObjectName]TriggerHandlerTest { // TODO: Assert all records inserted successfully // List inserted = [SELECT Id FROM Opportunity WHERE Name LIKE 'Bulk Opp%']; - // System.assertEquals(200, inserted.size(), 'Should insert all 200 records'); + // System.Assert.areEqual(200, inserted.size(), 'Should insert all 200 records'); } /** @@ -231,7 +231,7 @@ private class [ObjectName]TriggerHandlerTest { // TODO: Assert only qualifying records triggered side effects // List tasks = [SELECT Id FROM Task WHERE WhatId IN :testOpps]; - // System.assertEquals(25, tasks.size(), 'Should create tasks for 25 qualifying records'); + // System.Assert.areEqual(25, tasks.size(), 'Should create tasks for 25 qualifying records'); } /** @@ -257,9 +257,9 @@ private class [ObjectName]TriggerHandlerTest { Test.stopTest(); // Assert we're under governor limits - System.assert(Limits.getDmlStatements() < Limits.getLimitDmlStatements(), + System.Assert.isTrue(Limits.getDmlStatements() < Limits.getLimitDmlStatements(), 'Should not exceed DML statement limit'); - System.assert(Limits.getQueries() < Limits.getLimitQueries(), + System.Assert.isTrue(Limits.getQueries() < Limits.getLimitQueries(), 'Should not exceed SOQL query limit'); } @@ -278,7 +278,7 @@ private class [ObjectName]TriggerHandlerTest { Test.stopTest(); // If we get here without exception, test passes - System.assert(true, 'Handler should handle empty collections gracefully'); + System.Assert.isTrue(true, 'Handler should handle empty collections gracefully'); } /** @@ -310,11 +310,11 @@ private class [ObjectName]TriggerHandlerTest { WHERE WhatId IN :oppIds ]; - System.assertEquals(expectedCount, tasks.size(), + System.Assert.areEqual(expectedCount, tasks.size(), 'Should create ' + expectedCount + ' task(s)'); if (expectedCount > 0) { - System.assertEquals(subject, tasks[0].Subject, + System.Assert.areEqual(subject, tasks[0].Subject, 'Task subject should match'); } } diff --git a/skills/testing-automation/apex-test-class/SKILL.md b/skills/testing-automation/apex-test-class/SKILL.md index 235e207..c595f14 100644 --- a/skills/testing-automation/apex-test-class/SKILL.md +++ b/skills/testing-automation/apex-test-class/SKILL.md @@ -16,7 +16,7 @@ description: Apex test class generation with TestDataFactory patterns, bulk test ## Test Class Structure ```apex -@isTest +@IsTest private class MyServiceTest { @TestSetup @@ -25,7 +25,7 @@ private class MyServiceTest { List accounts = TestDataFactory.createAccounts(200, true); } - @isTest + @IsTest static void shouldPerformExpectedBehavior_WhenValidInput() { // Given: Setup specific test state List accounts = [SELECT Id, Name FROM Account]; @@ -37,13 +37,13 @@ private class MyServiceTest { // Then: Assert expected outcomes List updated = [SELECT Id, Status__c FROM Account]; - System.assertEquals(200, updated.size(), 'All accounts should be processed'); + System.Assert.areEqual(200, updated.size(), 'All accounts should be processed'); for (Account acc : updated) { - System.assertEquals('Processed', acc.Status__c, 'Status should be updated'); + System.Assert.areEqual('Processed', acc.Status__c, 'Status should be updated'); } } - @isTest + @IsTest static void shouldThrowException_WhenInvalidInput() { // Given List emptyList = new List(); @@ -52,9 +52,9 @@ private class MyServiceTest { Test.startTest(); try { MyService.processAccounts(emptyList); - System.assert(false, 'Expected MyCustomException to be thrown'); + System.Assert.fail('Expected MyCustomException to be thrown'); } catch (MyCustomException e) { - System.assert(e.getMessage().contains('cannot be empty'), + System.Assert.isTrue(e.getMessage().contains('cannot be empty'), 'Exception message should indicate empty input'); } Test.stopTest(); diff --git a/skills/testing-automation/apex-test-class/references/assertion-patterns.md b/skills/testing-automation/apex-test-class/references/assertion-patterns.md index 4a67586..08a95e8 100644 --- a/skills/testing-automation/apex-test-class/references/assertion-patterns.md +++ b/skills/testing-automation/apex-test-class/references/assertion-patterns.md @@ -2,28 +2,41 @@ ## Assertion Methods +The `System.Assert` class provides methods to assert various conditions in test methods. All methods support an optional message parameter for better error reporting. + | Method | Use Case | |--------|----------| -| `System.assertEquals(expected, actual, msg)` | Exact equality | -| `System.assertNotEquals(expected, actual, msg)` | Value should differ | -| `System.assert(condition, msg)` | Boolean condition | +| `System.Assert.areEqual(expected, actual, msg)` | Exact equality | +| `System.Assert.areNotEqual(notExpected, actual, msg)` | Value should differ | +| `System.Assert.isTrue(condition, msg)` | Boolean condition is true | +| `System.Assert.isFalse(condition, msg)` | Boolean condition is false | +| `System.Assert.isNull(value, msg)` | Value is null | +| `System.Assert.isNotNull(value, msg)` | Value is not null | +| `System.Assert.isInstanceOfType(instance, expectedType, msg)` | Instance is of specified type | +| `System.Assert.isNotInstanceOfType(instance, notExpectedType, msg)` | Instance is not of specified type | +| `System.Assert.fail(msg)` | Explicitly fail the test | -**Always include the third parameter (message)** - Makes test failures meaningful. +**Always include the message parameter** - Makes test failures meaningful and easier to debug. + +**Note:** Assertion failures are fatal errors that halt code execution. You cannot catch assertion failures using try/catch blocks, even though they're logged as exceptions. + + +**Note:** Call `startTest()` and `stopTest()` only once per test method. Wrap only the code under test between these calls, not setup or verification code. ## Good vs Bad Assertions ### ❌ Bad: No message, tests coverage not behavior ```apex -System.assertEquals(true, result); -System.assert(accounts.size() > 0); +System.Assert.areEqual(true, result); +System.Assert.isTrue(accounts.size() > 0); ``` ### ✅ Good: Descriptive message, tests specific behavior ```apex -System.assertEquals(true, result, 'Service should return true for valid input'); -System.assertEquals(200, accounts.size(), 'All 200 accounts should be processed'); +System.Assert.areEqual(true, result, 'Service should return true for valid input'); +System.Assert.areEqual(200, accounts.size(), 'All 200 accounts should be processed'); ``` ## Common Assertion Patterns @@ -32,24 +45,24 @@ System.assertEquals(200, accounts.size(), 'All 200 accounts should be processed' ```apex // Exact count -System.assertEquals(200, results.size(), 'Should process all 200 records'); +System.Assert.areEqual(200, results.size(), 'Should process all 200 records'); // Not empty -System.assert(!results.isEmpty(), 'Results should not be empty'); +System.Assert.isFalse(results.isEmpty(), 'Results should not be empty'); // Empty -System.assert(results.isEmpty(), 'No results expected for invalid input'); +System.Assert.isTrue(results.isEmpty(), 'No results expected for invalid input'); ``` ### Field Values ```apex // Single record -System.assertEquals('Processed', acc.Status__c, 'Account status should be updated to Processed'); +System.Assert.areEqual('Processed', acc.Status__c, 'Account status should be updated to Processed'); // All records in collection for (Account acc : updatedAccounts) { - System.assertEquals('Active', acc.Status__c, + System.Assert.areEqual('Active', acc.Status__c, 'Account ' + acc.Name + ' should have Active status'); } ``` @@ -57,8 +70,8 @@ for (Account acc : updatedAccounts) { ### Exception Testing ```apex -@isTest -static void shouldThrowException_WhenInputInvalid() { +@IsTest +private static void shouldThrowException_WhenInputInvalid() { Boolean exceptionThrown = false; String exceptionMessage = ''; @@ -71,8 +84,8 @@ static void shouldThrowException_WhenInputInvalid() { } Test.stopTest(); - System.assert(exceptionThrown, 'MyCustomException should be thrown for null input'); - System.assert(exceptionMessage.contains('cannot be null'), + System.Assert.isTrue(exceptionThrown, 'MyCustomException should be thrown for null input'); + System.Assert.isTrue(exceptionMessage.contains('cannot be null'), 'Exception message should mention null input'); } ``` @@ -83,13 +96,13 @@ static void shouldThrowException_WhenInputInvalid() { // Insert success Database.SaveResult[] results = Database.insert(accounts, false); for (Database.SaveResult sr : results) { - System.assert(sr.isSuccess(), 'Insert should succeed: ' + sr.getErrors()); + System.Assert.isTrue(sr.isSuccess(), 'Insert should succeed: ' + sr.getErrors()); } // Expected failures Database.SaveResult sr = Database.insert(invalidAccount, false); -System.assert(!sr.isSuccess(), 'Insert should fail for invalid data'); -System.assert(sr.getErrors()[0].getMessage().contains('REQUIRED_FIELD_MISSING'), +System.Assert.isFalse(sr.isSuccess(), 'Insert should fail for invalid data'); +System.Assert.isTrue(sr.getErrors()[0].getMessage().contains('REQUIRED_FIELD_MISSING'), 'Error should indicate missing required field'); ``` @@ -97,11 +110,11 @@ System.assert(sr.getErrors()[0].getMessage().contains('REQUIRED_FIELD_MISSING'), ```apex // Compare specific fields, not entire objects -System.assertEquals(expected.Name, actual.Name, 'Names should match'); -System.assertEquals(expected.Status__c, actual.Status__c, 'Status should match'); +System.Assert.areEqual(expected.Name, actual.Name, 'Names should match'); +System.Assert.areEqual(expected.Status__c, actual.Status__c, 'Status should match'); // Or use JSON for deep comparison (use sparingly) -System.assertEquals( +System.Assert.areEqual( JSON.serialize(expected), JSON.serialize(actual), 'Objects should be identical' @@ -112,11 +125,11 @@ System.assertEquals( ```apex // Exact date -System.assertEquals(Date.today(), record.CreatedDate__c, 'Should be created today'); +System.Assert.areEqual(Date.today(), record.CreatedDate__c, 'Should be created today'); // Date within range -System.assert(record.DueDate__c >= Date.today(), 'Due date should be in the future'); -System.assert(record.DueDate__c <= Date.today().addDays(30), +System.Assert.isTrue(record.DueDate__c >= Date.today(), 'Due date should be in the future'); +System.Assert.isTrue(record.DueDate__c <= Date.today().addDays(30), 'Due date should be within 30 days'); ``` @@ -124,10 +137,41 @@ System.assert(record.DueDate__c <= Date.today().addDays(30), ```apex // Should be null -System.assertEquals(null, result.ErrorMessage__c, 'No error expected for valid input'); +System.Assert.isNull(result.ErrorMessage__c, 'No error expected for valid input'); // Should not be null -System.assertNotEquals(null, result.Id, 'Record should have been inserted'); +System.Assert.isNotNull(result.Id, 'Record should have been inserted'); +``` + +### Type Checking + +```apex +// Verify instance is of expected type +Object result = MyService.processData(); +System.Assert.isInstanceOfType(result, MyCustomClass.class, + 'Result should be an instance of MyCustomClass'); + +// Verify instance is not of a specific type +Object handler = HandlerFactory.create('Account'); +System.Assert.isNotInstanceOfType(handler, ContactHandler.class, + 'Account handler should not be a ContactHandler'); +``` + +### Explicit Test Failures + +```apex +// Use Assert.fail() when an exception should have been thrown but wasn't +@IsTest +private static void shouldThrowException_WhenInputInvalid() { + try { + MyService.process(null); + System.Assert.fail('Expected MyCustomException to be thrown for null input'); + } catch (MyCustomException e) { + // Exception was thrown as expected, test passes + System.Assert.isTrue(e.getMessage().contains('cannot be null'), + 'Exception message should mention null input'); + } +} ``` ## Anti-Patterns to Avoid @@ -136,20 +180,20 @@ System.assertNotEquals(null, result.Id, 'Record should have been inserted'); ```apex // Bad: Testing that a specific method was called -System.assert(MyClass.methodWasCalled, 'Method should be called'); +System.Assert.isTrue(MyClass.methodWasCalled, 'Method should be called'); // Good: Testing the observable outcome -System.assertEquals('Expected Value', record.Field__c, 'Field should be updated'); +System.Assert.areEqual('Expected Value', record.Field__c, 'Field should be updated'); ``` ### ❌ Overly generic assertions ```apex // Bad: Passes for any non-empty result -System.assert(results.size() > 0); +System.Assert.isTrue(results.size() > 0); // Good: Verifies exact expected count -System.assertEquals(200, results.size(), 'All 200 records should be returned'); +System.Assert.areEqual(200, results.size(), 'All 200 records should be returned'); ``` ### ❌ Missing negative test assertions @@ -160,6 +204,6 @@ MyService.process(data); // Test passes if no exception // Good: Verifies the actual outcome Result r = MyService.process(data); -System.assertEquals('Success', r.status, 'Processing should succeed'); -System.assertEquals(0, r.errorCount, 'No errors should occur'); +System.Assert.areEqual('Success', r.status, 'Processing should succeed'); +System.Assert.areEqual(0, r.errorCount, 'No errors should occur'); ``` \ No newline at end of file diff --git a/skills/testing-automation/apex-test-class/references/async-testing.md b/skills/testing-automation/apex-test-class/references/async-testing.md index db651f9..e12412c 100644 --- a/skills/testing-automation/apex-test-class/references/async-testing.md +++ b/skills/testing-automation/apex-test-class/references/async-testing.md @@ -9,8 +9,8 @@ ### Basic Batch Test ```apex -@isTest -static void shouldProcessAllRecords_WhenBatchExecutes() { +@IsTest +private static void shouldProcessAllRecords_WhenBatchExecutes() { // Given: Create test data List accounts = TestDataFactory.createAccounts(200, true); @@ -23,7 +23,7 @@ static void shouldProcessAllRecords_WhenBatchExecutes() { // Then: Verify results List updated = [SELECT Id, Status__c FROM Account]; for (Account acc : updated) { - System.assertEquals('Processed', acc.Status__c, + System.Assert.areEqual('Processed', acc.Status__c, 'Batch should update all account statuses'); } } @@ -32,8 +32,8 @@ static void shouldProcessAllRecords_WhenBatchExecutes() { ### Testing Batch with Failures ```apex -@isTest -static void shouldLogErrors_WhenRecordsFail() { +@IsTest +private static void shouldLogErrors_WhenRecordsFail() { // Given: Create mix of valid and invalid records List accounts = TestDataFactory.createAccounts(198, true); @@ -55,15 +55,15 @@ static void shouldLogErrors_WhenRecordsFail() { // Then List errors = [SELECT Id, Message__c FROM Error_Log__c]; - System.assertEquals(2, errors.size(), 'Should log 2 failed records'); + System.Assert.areEqual(2, errors.size(), 'Should log 2 failed records'); } ``` ### Testing Batch Scope ```apex -@isTest -static void shouldRespectBatchSize() { +@IsTest +private static void shouldRespectBatchSize() { // Given List accounts = TestDataFactory.createAccounts(250, true); @@ -74,7 +74,7 @@ static void shouldRespectBatchSize() { // Note: In tests, all batches execute but you can verify total processing List processed = [SELECT Id FROM Account WHERE Processed__c = true]; - System.assertEquals(250, processed.size(), 'All records should be processed'); + System.Assert.areEqual(250, processed.size(), 'All records should be processed'); } ``` @@ -83,8 +83,8 @@ static void shouldRespectBatchSize() { ### Basic Queueable Test ```apex -@isTest -static void shouldCompleteProcessing_WhenQueueableEnqueued() { +@IsTest +private static void shouldCompleteProcessing_WhenQueueableEnqueued() { // Given Account acc = TestDataFactory.createAccount(true); @@ -96,7 +96,7 @@ static void shouldCompleteProcessing_WhenQueueableEnqueued() { // Then Account updated = [SELECT Id, Status__c FROM Account WHERE Id = :acc.Id]; - System.assertEquals('Processed', updated.Status__c, + System.Assert.areEqual('Processed', updated.Status__c, 'Queueable should update account status'); } ``` @@ -106,8 +106,8 @@ static void shouldCompleteProcessing_WhenQueueableEnqueued() { Chained queueables only execute the first job in tests: ```apex -@isTest -static void shouldChainNextJob_WhenMoreRecordsExist() { +@IsTest +private static void shouldChainNextJob_WhenMoreRecordsExist() { // Given: More records than one queueable can process List accounts = TestDataFactory.createAccounts(500, true); @@ -119,7 +119,7 @@ static void shouldChainNextJob_WhenMoreRecordsExist() { // Verify first batch processed List processed = [SELECT Id FROM Account WHERE Processed__c = true]; - System.assertEquals(100, processed.size(), 'First batch should process 100 records'); + System.Assert.areEqual(100, processed.size(), 'First batch should process 100 records'); // Verify chain was enqueued (check AsyncApexJob) List jobs = [ @@ -127,15 +127,15 @@ static void shouldChainNextJob_WhenMoreRecordsExist() { FROM AsyncApexJob WHERE ApexClass.Name = 'MyChainedQueueable' ]; - System.assert(jobs.size() >= 1, 'Chained job should be enqueued'); + System.Assert.isTrue(jobs.size() >= 1, 'Chained job should be enqueued'); } ``` ### Testing Queueable with Callouts ```apex -@isTest -static void shouldMakeCallout_WhenQueueableWithCallout() { +@IsTest +private static void shouldMakeCallout_WhenQueueableWithCallout() { // Given Test.setMock(HttpCalloutMock.class, new MockHttpResponse(200, '{"status":"ok"}')); Account acc = TestDataFactory.createAccount(true); @@ -148,7 +148,7 @@ static void shouldMakeCallout_WhenQueueableWithCallout() { // Then Account updated = [SELECT Id, External_Status__c FROM Account WHERE Id = :acc.Id]; - System.assertEquals('Synced', updated.External_Status__c, + System.Assert.areEqual('Synced', updated.External_Status__c, 'Should update status after successful callout'); } ``` @@ -156,8 +156,8 @@ static void shouldMakeCallout_WhenQueueableWithCallout() { ## Future Method Testing ```apex -@isTest -static void shouldExecuteFutureMethod() { +@IsTest +private static void shouldExecuteFutureMethod() { // Given Account acc = TestDataFactory.createAccount(true); @@ -168,7 +168,7 @@ static void shouldExecuteFutureMethod() { // Then Account updated = [SELECT Id, Processed__c FROM Account WHERE Id = :acc.Id]; - System.assertEquals(true, updated.Processed__c, 'Future should process record'); + System.Assert.areEqual(true, updated.Processed__c, 'Future should process record'); } ``` @@ -177,8 +177,8 @@ static void shouldExecuteFutureMethod() { ### Testing Scheduled Execution ```apex -@isTest -static void shouldExecuteScheduledJob() { +@IsTest +private static void shouldExecuteScheduledJob() { // Given List accounts = TestDataFactory.createAccounts(50, true); @@ -194,15 +194,15 @@ static void shouldExecuteScheduledJob() { // Then List processed = [SELECT Id FROM Account WHERE Processed__c = true]; - System.assertEquals(50, processed.size(), 'Scheduled job should process records'); + System.Assert.areEqual(50, processed.size(), 'Scheduled job should process records'); } ``` ### Testing Schedule Registration ```apex -@isTest -static void shouldScheduleJob() { +@IsTest +private static void shouldScheduleJob() { Test.startTest(); String cronExp = '0 0 6 * * ?'; // Daily at 6 AM String jobId = System.schedule('Daily Processing', cronExp, new MyScheduledClass()); @@ -214,16 +214,16 @@ static void shouldScheduleJob() { FROM CronTrigger WHERE Id = :jobId ]; - System.assertEquals('0 0 6 * * ?', ct.CronExpression, 'CRON should match'); - System.assertEquals('WAITING', ct.State, 'Job should be waiting'); + System.Assert.areEqual('0 0 6 * * ?', ct.CronExpression, 'CRON should match'); + System.Assert.areEqual('WAITING', ct.State, 'Job should be waiting'); } ``` ## Testing Async Limits ```apex -@isTest -static void shouldNotExceedQueueableLimits() { +@IsTest +private static void shouldNotExceedQueueableLimits() { // Given: Setup that might enqueue multiple jobs List accounts = TestDataFactory.createAccounts(100, true); @@ -236,7 +236,7 @@ static void shouldNotExceedQueueableLimits() { Test.stopTest(); // Verify limit not exceeded (50 in synchronous context, 1 in queueable) - System.assert(queueablesUsed <= 50, + System.Assert.isTrue(queueablesUsed <= 50, 'Should not exceed queueable limit. Used: ' + queueablesUsed); } ``` @@ -252,7 +252,7 @@ System.enqueueJob(new MyQueueable()); // Missing Test.stopTest()! List results = [SELECT Id FROM Account WHERE Processed__c = true]; -System.assertEquals(100, results.size()); // FAILS - queueable didn't run +System.Assert.areEqual(100, results.size()); // FAILS - queueable didn't run ``` ### ❌ Testing chained jobs without understanding limits diff --git a/skills/testing-automation/apex-test-class/references/mocking-patterns.md b/skills/testing-automation/apex-test-class/references/mocking-patterns.md index a308227..f18361a 100644 --- a/skills/testing-automation/apex-test-class/references/mocking-patterns.md +++ b/skills/testing-automation/apex-test-class/references/mocking-patterns.md @@ -7,7 +7,7 @@ Apex doesn't allow real HTTP callouts in tests. Use `HttpCalloutMock` interface. ### Basic Mock Implementation ```apex -@isTest +@IsTest public class MockHttpResponse implements HttpCalloutMock { private Integer statusCode; @@ -31,8 +31,8 @@ public class MockHttpResponse implements HttpCalloutMock { ### Using the Mock ```apex -@isTest -static void shouldProcessApiResponse_WhenCalloutSucceeds() { +@IsTest +private static void shouldProcessApiResponse_WhenCalloutSucceeds() { // Given String mockResponse = '{"status": "success", "data": [{"id": "123"}]}'; Test.setMock(HttpCalloutMock.class, new MockHttpResponse(200, mockResponse)); @@ -43,12 +43,12 @@ static void shouldProcessApiResponse_WhenCalloutSucceeds() { Test.stopTest(); // Then - System.assertEquals(1, results.size(), 'Should parse one record from response'); - System.assertEquals('123', results[0].externalId, 'Should extract correct ID'); + System.Assert.areEqual(1, results.size(), 'Should parse one record from response'); + System.Assert.areEqual('123', results[0].externalId, 'Should extract correct ID'); } -@isTest -static void shouldHandleError_WhenCalloutFails() { +@IsTest +private static void shouldHandleError_WhenCalloutFails() { // Given String errorResponse = '{"error": "Unauthorized"}'; Test.setMock(HttpCalloutMock.class, new MockHttpResponse(401, errorResponse)); @@ -59,8 +59,8 @@ static void shouldHandleError_WhenCalloutFails() { Test.stopTest(); // Then - System.assertEquals(false, result.isSuccess, 'Should indicate failure'); - System.assert(result.errorMessage.contains('Unauthorized'), 'Should capture error'); + System.Assert.areEqual(false, result.isSuccess, 'Should indicate failure'); + System.Assert.isTrue(result.errorMessage.contains('Unauthorized'), 'Should capture error'); } ``` @@ -69,7 +69,7 @@ static void shouldHandleError_WhenCalloutFails() { For services making multiple callouts: ```apex -@isTest +@IsTest public class MultiRequestMock implements HttpCalloutMock { private Map endpointResponses; @@ -116,8 +116,8 @@ Test.setMock(HttpCalloutMock.class, new MultiRequestMock(mocks)); For complex response bodies, store JSON in Static Resources: ```apex -@isTest -static void shouldParseComplexResponse() { +@IsTest +private static void shouldParseComplexResponse() { StaticResourceCalloutMock mock = new StaticResourceCalloutMock(); mock.setStaticResource('TestApiResponse'); // Static Resource name mock.setStatusCode(200); @@ -129,7 +129,7 @@ static void shouldParseComplexResponse() { Result r = MyService.callExternalApi(); Test.stopTest(); - System.assertNotEquals(null, r, 'Should parse response'); + System.Assert.isNotNull(r, 'Should parse response'); } ``` @@ -138,7 +138,7 @@ static void shouldParseComplexResponse() { For mocking Apex class dependencies using `System.StubProvider`: ```apex -@isTest +@IsTest public class MyServiceMock implements System.StubProvider { public Object handleMethodCall( @@ -157,8 +157,8 @@ public class MyServiceMock implements System.StubProvider { } // Usage in test: -@isTest -static void shouldUseAccountData() { +@IsTest +private static void shouldUseAccountData() { MyServiceMock mockProvider = new MyServiceMock(); IMyService mockService = (IMyService)Test.createStub(IMyService.class, mockProvider); @@ -169,7 +169,7 @@ static void shouldUseAccountData() { String result = controller.displayAccountInfo(); Test.stopTest(); - System.assert(result.contains('Mock Account'), 'Should use mocked data'); + System.Assert.isTrue(result.contains('Mock Account'), 'Should use mocked data'); } ``` @@ -178,8 +178,8 @@ static void shouldUseAccountData() { Apex sends real emails by default. Use limits to verify: ```apex -@isTest -static void shouldSendEmail_WhenTriggered() { +@IsTest +private static void shouldSendEmail_WhenTriggered() { Integer emailsBefore = Limits.getEmailInvocations(); Test.startTest(); @@ -187,7 +187,7 @@ static void shouldSendEmail_WhenTriggered() { Test.stopTest(); // Verify email was queued (not actually sent in tests) - System.assertEquals( + System.Assert.areEqual( emailsBefore + 1, Limits.getEmailInvocations(), 'One email should be sent' @@ -198,8 +198,8 @@ static void shouldSendEmail_WhenTriggered() { ## Platform Event Testing ```apex -@isTest -static void shouldPublishEvent_WhenRecordCreated() { +@IsTest +private static void shouldPublishEvent_WhenRecordCreated() { Test.startTest(); // Enable event delivery in test context @@ -214,6 +214,6 @@ static void shouldPublishEvent_WhenRecordCreated() { // Query platform event trigger results List logs = [SELECT Id FROM EventLog__c WHERE AccountId__c = :acc.Id]; - System.assertEquals(1, logs.size(), 'Event handler should create log record'); + System.Assert.areEqual(1, logs.size(), 'Event handler should create log record'); } ``` diff --git a/skills/testing-automation/apex-test-class/references/test-data-factory.md b/skills/testing-automation/apex-test-class/references/test-data-factory.md index b4cc3df..3ae57a7 100644 --- a/skills/testing-automation/apex-test-class/references/test-data-factory.md +++ b/skills/testing-automation/apex-test-class/references/test-data-factory.md @@ -7,7 +7,7 @@ TestDataFactory is a centralized utility class for creating test records with se ## Base Template ```apex -@isTest +@IsTest public class TestDataFactory { // ============ ACCOUNTS ============