0

How can we unit test a random string generator class of this given code. I do get 100% code coverage, but I feel like the test is not executed properly. Any solutions to this will be helpful.

Random string generator code:

public class token {
    public static String createToken(){
        final String chars = 'A';
        String token = '';
        Integer x = 1;
        while (token.length() < x) {
            Integer idx = Math.mod(Math.abs(Crypto.getRandomInteger()), chars.length());
            token += chars.substring(idx, idx+1);
        }
        return token;
    }
}

Test class code (100% code coverage) :

@isTest
public class tokenTest {
    @isTest static void createTokenTest(){
        String tok = token.createToken();
        system.assertEquals('A', tok, 'doesn\'t work');
    }
}

will adding the random generator part in to a method and passing values help? meaning i can send in the required chars and length to get the desired output.

UPDATED - after @Phil W's answer, point 3 mentioned in his answer is not included in the test class code, as checking if the code is unique is tested in another trigger.

RSG code:

public class token {
    public static String createToken(){
        final String chars = 'ABCDEFGHJKLMNPRSTUWXYZ123456789';
        String token = '';
        Integer x = 6;
        while (token.length() < x) {
            Integer idx = Math.mod(Math.abs(Crypto.getRandomInteger()), chars.length());
            token += chars.substring(idx, idx+1);
        }
        return token;
    }
}

Test Class code:

@isTest
public class tokenTest {
    @isTest static void tokenLengthTest(){
        String tok = token.createToken();
        system.assertEquals(6, tok.length(), 'doesn\'t work');
    }
    @isTest static void tokenCharacterTest(){
        String tok = token.createToken();
        final String charsTest = 'ABCDEFGHJKLMNPRSTUWXYZ123456789';
        final String charsNotTest = 'OQV0I!@#$%^&*()_+,.\'][<>?';
        system.assert(tok.containsOnly(charsTest), 'Failed at checking given characters, meaning string has invalid characters');
        system.assert(!tok.containsOnly(charsNotTest), 'Failed at checking invalid characters, meaning string has invalid characters');
    }
}
3
  • 1
    I think actual randomized number difficult to predict, its better to use mock string Apr 4, 2019 at 6:30
  • sure it might be hard to predict, but if i set char to AB and integer 1, it will either create A or B. Meaning i can write a system.assertEquals for both. Or even set char as A, it will only create A as the random number. So the test won't fail. but i cannot figure out how to write this. can you please help Apr 4, 2019 at 6:34
  • 1
    I would think that you could check that the token conforms to your expectations: it is the correct length, it only contains the desired characters and that you get a different value n% of the time on average (where n depends on the length of number of options for each digit).
    – Phil W
    Apr 4, 2019 at 7:07

2 Answers 2

5

You should not be testing the results against a fixed set of options but rather that:

  1. The token is the correct length
  2. The token is made up of the correct characters
  3. The token is different on average n% of the time where n depends on the token length and number of options per character.
1
  • 1
    wow thanks for this, never thought of it in this way. Apr 4, 2019 at 7:50
1

@Phil W's is the best answer, but if you had a fixed set of strings you wanted to test again, then you could use Set<String> and then use the System.assert() like so:

@isTest static void createTokenTest(){
    String tok = token.createToken();
    Set<String> validTokens = new Set<String>{'A','AB','B'};    // You could move this into the actual Token class as a static final variable
    System.assert(validTokens.contains(tok), tok + ' is not a valid token');
}

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.