JUnit — Тестовые случаи для проверки кредитных карт в качестве проекта Maven

Опубликовано: 19 Февраля, 2023

В этой статье мы рассмотрим столь необходимую функциональность, а именно проверку кредитной карты, а также соответствующие тестовые примеры JUnit для заданных номеров кредитных карт. В проекте электронной коммерции оплата кредитной картой является действительной и очень желательной необходимой функцией. Для этого нам нужен надлежащий механизм проверки. Итак, с помощью «алгоритма Луна» выполняется код проверки. В качестве проекта maven давайте рассмотрим проверку, а также часть тестового примера JUnit.

Пример проекта Maven

Структура проекта:

Зависимости должны быть указаны в

пом.xml

XML




<?xml version="1.0" encoding="UTF-8"?>
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
                             http://maven.apache.org/xsd/maven-4.0.0.xsd">
  
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.gfg.CreditCardUtilityServices</groupId>
    <artifactId>CreditCardUtilityServices</artifactId>
    <packaging>jar</packaging>
    <version>1.0-SNAPSHOT</version>
  
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <junit.version>5.3.1</junit.version>
        <pitest.version>1.4.3</pitest.version>
    </properties>
  
    <dependencies>
  
        <!-- junit 5, unit test -->
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-engine</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
  
    </dependencies>
    <build>
        <finalName>UtilityServices</finalName>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>3.0.0-M1</version>
            </plugin>
  
            <plugin>
                <groupId>org.pitest</groupId>
                <artifactId>pitest-maven</artifactId>
                <version>${pitest.version}</version>
  
                <executions>
                    <execution>
                        <id>pit-report</id>
                        <phase>test</phase>
                        <goals>
                            <goal>mutationCoverage</goal>
                        </goals>
                    </execution>
                </executions>
  
                <!-- https://github.com/hcoles/pitest/issues/284 -->
                <!-- Need this to support JUnit 5 -->
                <dependencies>
                    <dependency>
                        <groupId>org.pitest</groupId>
                        <artifactId>pitest-junit5-plugin</artifactId>
                        <version>0.8</version>
                    </dependency>
                </dependencies>
                <configuration>
                    <targetClasses>
                        <param>com.gfg.CreditCardUtilityServices.*CreditCardUtilityServices*</param>
                          
                    </targetClasses>
                    <targetTests>
                        <param>com.gfg.CreditCardUtilityServices.*</param>
                    </targetTests>
                </configuration>
            </plugin>
  
        </plugins>
    </build>
  
</project>

Теперь давайте напишем бизнес-логику проверки кредитной карты.

CreditCardValidation.java

Java




public class CreditCardValidation {   
   
    /* Return true if the card number is valid by using Luhn algorithm.
    Prerequisites
        A credit card number must have between 13 and 16 digits. 
        It must start with:
        4 for Visa cards
        5 for Master cards
        37 for American Express cards
        6 for Discover cards
    */
    public static boolean checkForValidity(long number)
    {
       return (getNumberOfDigits(number) >= 13 &&
               getNumberOfDigits(number) <= 16) &&
               (checkForPrefixMatching(number, 4) ||
                checkForPrefixMatching(number, 5) ||
                checkForPrefixMatching(number, 37) ||
                checkForPrefixMatching(number, 6)) &&
              ((sumOfDoubleEvenPlaces(number) +
                getSumOfOddPlaces(number)) % 10 == 0);
    }
   
    // Get the result from Step 2
    public static int sumOfDoubleEvenPlaces(long inputNumber)
    {
        int summation = 0;
        String number = inputNumber + "";
        for (int i = getNumberOfDigits(inputNumber) - 2; i >= 0; i -= 2)
            summation += getTheDigits(Integer.parseInt(number.charAt(i) + "") * 2);
           
        return summation;
    }
   
    // When the input number is a single digit that 
    // means between 0 to 9, Return this number as it is
    // If not, 
    // return the sum of the two digits
    public static int getTheDigits(int inputNumber)
    {
        if (inputNumber < 9)
            return inputNumber;
        return inputNumber / 10 + inputNumber % 10;
    }
   
    // We are going to add the odd-place digits 
      // in number and return their sum
    public static int getSumOfOddPlaces(long inputnumber)
    {
        int summation = 0;
        String number = inputnumber + "";
        // As odd places, we need to decrement by 2
        for (int i = getNumberOfDigits(inputnumber) - 1; i >= 0; i -= 2)
            summation += Integer.parseInt(number.charAt(i) + "");       
        return summation;
    }
   
    // Return true if the digit  is a prefix for number
    public static boolean checkForPrefixMatching(long inputnumber, int digit)
    {
        return getPrefixNumber(inputnumber, getNumberOfDigits(digit)) == digit;
    }
   
    // Return the number of digits
    public static int getNumberOfDigits(long digit)
    {
        String number = digit + "";
        return number.length();
    }
   
    // By using substring functionality, we can 
    // return the first k number of digits from
    // number. If the number of digits in number
    // is less than k, return number.
    public static long getPrefixNumber(long inputnumber, int k)
    {
        if (getNumberOfDigits(inputnumber) > k) {
            String num = inputnumber + "";
            return Long.parseLong(num.substring(0, k));
        }
        return inputnumber;
    }
}

Теперь давайте перейдем к тестам JUNIT. Он охватывает несколько действительных номеров тестовых кредитных карт от «American Express, Diners Club, Master, Visa и т. д.».

TestCreditCardService.java

Java




import static org.junit.jupiter.api.Assertions.assertAll;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assumptions.assumeFalse;
import static org.junit.jupiter.api.Assumptions.assumingThat;
  
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
  
public class TestCreditCardService {
    @Test
    public void testForValidCreditCardNumbers() {
        // Example for American Express card
        assertEquals(true, CreditCardValidation.checkForValidity(378282246310005L));
        assertNotEquals(true, CreditCardValidation.checkForValidity(37828224631015L));
            
        // Example for American Express Corporate card
        assertEquals(true, CreditCardValidation.checkForValidity(378734493671000L));
            
        // Example for Discover card
        assertTrue(CreditCardValidation.checkForValidity(6011111111111117L));
        assertFalse(CreditCardValidation.checkForValidity(6011111111111128L),"Invalid Creditcard");
        String validationName = "creditCardValidation";
          
         // In a grouped assertion all assertions are executed, and any
        // failures will be reported together.
        // Example for Master card and Visa
        assertAll("creditCardValidation", () -> assertTrue(CreditCardValidation.checkForValidity(5105105105105100L)),
                () -> assertTrue(CreditCardValidation.checkForValidity(4111111111111111L)));
        // Let us comment for the first time
        // assertAll("creditCardValidationYieldingFalse", () -> assertTrue(CreditCardValidation.checkForValidity(378282246310005L)),
        //                 () -> assertTrue(CreditCardValidation.checkForValidity(378282246310005L)));
          
        /* The assumingThat() method executes the rest of the statements 
           if the assumption is valid. If the assumption is invalid, 
           this method does nothing. 
           Advantage : To log the information
        */
        
       // Example for Visa card
       assumingThat("creditCardValidation".equals(validationName), () -> {
            System.out.println("Checking for creditcard validation!!!");
            assertEquals(true, CreditCardValidation.checkForValidity(4012888888881881L));
        });
        
        /* with assumeFalse
        * If the boolean condition in assumeFalse becomes false 
        * then only the next set of test method is executed, 
        * else the test is skipped. 
        */       
        assumeFalse("loginValidation".equals(validationName));
        
        // Example for Paymentech (Processor specific card)
        assertTrue(CreditCardValidation.checkForValidity(6331101999990016L));
        
        // Example for American Express,Diners and Master card (May be 3 people at a home are having 3 different cards, 
        // we can check in this way, instead of checking single single
        assertArrayEquals(new long[]{378282246310005L,30569309025904L,5555555555554444L},new long[]{378282246310005L,30569309025904L,5555555555554444L});
        Assertions.assertThrows(IllegalArgumentException.class, () -> {
            Integer.parseInt("378282246310005L");
        });
        
    }  
      
}

Объяснение для assertAll:

Иногда возникает необходимость предоставления положительных результатов и проверки нескольких условий.

 assertAll("creditCardValidation", () -> assertTrue(CreditCardValidation.checkForValidity(5105105105105100L)),
                () -> assertTrue(CreditCardValidation.checkForValidity(4111111111111111L)));

Здесь записываются два отдельных утверждения assertTrue, и оба должны быть истинными, т. е. данная карта должна быть проверена как истинная, а затем передается только все условие.

В приведенном выше коде давайте раскомментируем приведенный ниже код.

assertAll("creditCardValidationYieldingFalse", () -> assertTrue(CreditCardValidation.checkForValidity(378282246310005L)),
               () -> assertTrue(CreditCardValidation.checkForValidity(379382246310005L)));

Среди двух данных карт первая является действительной картой, а вторая недействительной. Следовательно, все условие становится ложным, и мы можем видеть, что из результата также

Для получения сгруппированных результатов теста assertAll очень полезен.

при условии, что:

Бывают ситуации, когда нужно продолжить выполнение тестового примера. Для этого сценария мы можем использовать

// Example for Visa card
assumingThat("creditCardValidation".equals(validationName), () -> { // Only when the condition is valid
            System.out.println("Checking for creditcard validation!!!");// We can log the required information here
            assertEquals(true, CreditCardValidation.checkForValidity(4012888888881881L));
        });

По иронии судьбы, чтобы что-то проверить, мы можем использовать

предположить Ложь:

/* with assumeFalse
  * If the boolean condition in assumeFalse becomes false then only the next set of test method is executed, 
  * else the test is skipped. 
*/
       
// false here and hence next statement is proceeded
assumeFalse("loginValidation".equals(validationName)); 
// Example for Paymentech (Processor specific card)
assertTrue(CreditCardValidation.checkForValidity(6331101999990016L));

утверждать массив равных:

Вместо того, чтобы тестировать одну карту, мы можем поместить все в массив и проверить это.

// Example for American Express,Diners and Master card (May be 3 people at a home are having 3 different cards, we can check in this way, instead of checking single single
assertArrayEquals(new long[]{378282246310005L,30569309025904L,5555555555554444L},new long[]{378282246310005L,30569309025904L,5555555555554444L});

Таким образом, JUnit очень помогает получить качественное программное обеспечение. Написав эффективные JUnits, вы, безусловно, сможете создать лучшее программное обеспечение.