0

I want to cover this method :

@AuraEnabled
public static void  endUserSession(Id userId){
    List<AuthSession> uSessions = [ select Id , UsersId FROM  AuthSession  WHERE  UsersId =:userId AND  IsCurrent = TRUE ];
    if (!uSessions.isEmpty()) {
        delete uSessions;
    }
}

Since we can not create AuthSession in test class , I need to mock it and to mock it I create an interface :

public interface IDatabaseWrapper {
    List<SObject> queryWithBinds(
        String queryString,
        Map<String, Object> bindMap,
        System.AccessLevel accessLevel
    );
}

and class that implement the interface :

public without sharing class DatabaseWrapper implements IDatabaseWrapper {
    public List<SObject> queryWithBinds(
        String queryString,
        Map<String, Object> bindMap,
        System.AccessLevel accessLevel
    ) {
        return Database.queryWithBinds(queryString, bindMap, accessLevel);
    }
}

and here's how I modified my main method :

@TestVisible
private static IDatabaseWrapper db = new DatabaseWrapper();

@AuraEnabled
public static void  endUserSession(Id userId){
    List<AuthSession> uSessions = db.queryWithBinds(
        'select Id , UsersId FROM  AuthSession  WHERE  UsersId =:userId AND  IsCurrent = TRUE',
        new Map<String, Object>{
            'userId' => userId
        },
        System.AccessLevel.USER_MODE
    );
    if (!uSessions.isEmpty()) {
        delete uSessions;
    }
}

But i'm blocked on how to create its test method , how to inject a mock implementation of IDatabaseWrapper

1 Answer 1

0

I strongly recommend using whole words for variable names. That caveat aside, you simply need to assign a new value to db. You need to define a mock type first, either in your given test class or, if it has wide utility, in a separate top level mock. An example of the latter is included below.

@IsTest
public class MyDatabaseMock implements IDatabaseWrapper
{
    final List<SObject> records;
    public MyDatabaseMock(List<SObject> records) { this.records = records; }
    public List<SObject> queryWithBinds(
        String queryString, Map<String, Object> bindMap, AccessLevel accessLevel
    ){
        return records;
    }
}

You can add more nuance, but that's the basic idea. Then in your test, simply add this line before executing your method. You have to build mockRecords in memory first.

MyClass.db = new MyDatabaseMock(mockRecords);
4
  • I was able to cover my method by using : ApcFooterController.endUserSession(Auth.SessionManagement.getCurrentSession().get('UsersId')); List<AuthSession> sessionsAfterDelete = [SELECT Id FROM AuthSession WHERE UsersId = :testUser.Id]; System.assertEquals(0, sessionsAfterDelete.size(), 'AuthSessions should be deleted'); I didn't understand how to create MockRecords for AuthSession ..
    – Fark
    Commented Sep 16, 2023 at 18:10
  • You should be able to just construct them in memory. AuthSession session = new AuthSession(/*fields*/);
    – Adrian Larson
    Commented Sep 16, 2023 at 20:16
  • i couldn't , its read only object .. i showed you the "temporary solution"
    – Fark
    Commented Sep 16, 2023 at 20:22
  • Generally the other option is to construct a Map<String, Object>, serialize it, then deserialize back out into the type you need.
    – Adrian Larson
    Commented Sep 18, 2023 at 11:17

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .