Merge pull request #6 from mitchspano/apex_updates

Test method annotations to `@IsTest` and  `System.Assert` class
This commit is contained in:
Jeff Douglas 2026-01-30 16:08:01 -05:00 committed by GitHub
commit 85c1fe6075
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 156 additions and 112 deletions

View File

@ -54,7 +54,7 @@ private class [ObjectName]TriggerHandlerTest {
// TODO: Add assertions
// List<Opportunity> 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<Task> 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<Task> 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<Opportunity> 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<Task> 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');
}
}

View File

@ -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<Account> accounts = TestDataFactory.createAccounts(200, true);
}
@isTest
@IsTest
static void shouldPerformExpectedBehavior_WhenValidInput() {
// Given: Setup specific test state
List<Account> accounts = [SELECT Id, Name FROM Account];
@ -37,13 +37,13 @@ private class MyServiceTest {
// Then: Assert expected outcomes
List<Account> 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<Account> emptyList = new List<Account>();
@ -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();

View File

@ -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');
```

View File

@ -9,8 +9,8 @@
### Basic Batch Test
```apex
@isTest
static void shouldProcessAllRecords_WhenBatchExecutes() {
@IsTest
private static void shouldProcessAllRecords_WhenBatchExecutes() {
// Given: Create test data
List<Account> accounts = TestDataFactory.createAccounts(200, true);
@ -23,7 +23,7 @@ static void shouldProcessAllRecords_WhenBatchExecutes() {
// Then: Verify results
List<Account> 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<Account> accounts = TestDataFactory.createAccounts(198, true);
@ -55,15 +55,15 @@ static void shouldLogErrors_WhenRecordsFail() {
// Then
List<Error_Log__c> 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<Account> 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<Account> 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<Account> accounts = TestDataFactory.createAccounts(500, true);
@ -119,7 +119,7 @@ static void shouldChainNextJob_WhenMoreRecordsExist() {
// Verify first batch processed
List<Account> 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<AsyncApexJob> 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<Account> accounts = TestDataFactory.createAccounts(50, true);
@ -194,15 +194,15 @@ static void shouldExecuteScheduledJob() {
// Then
List<Account> 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<Account> 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<Account> 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

View File

@ -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<String, HttpResponse> 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<EventLog__c> 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');
}
```

View File

@ -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 ============