将 ArchUnit 测试应用于类或方法

问题描述 投票:0回答:1

我定义了以下 ArchUnit 测试来验证

  1. 任何使用 Spring 的

    @Transactional
    注解的类或方法也必须使用
    @Service

    注解
  2. 注释

    @jakarta.transaction.Transactional
    不允许出现在任何类或方法上

import com.tngtech.archunit.junit.ArchTest;
import com.tngtech.archunit.lang.ArchRule;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.*;

class TransactionRules {

    @ArchTest // test rule 1 for classes
    static final ArchRule transactionalServiceClasses = classes()
        .that().areAnnotatedWith(Transactional.class)
        .should().beAnnotatedWith(Service.class);

    @ArchTest // test rule 1 for methods
    static final ArchRule transactionalServiceMethods = methods()
        .that().areAnnotatedWith(Transactional.class)
        .should().beDeclaredInClassesThat().areAnnotatedWith(Service.class);

    @ArchTest // test rule 2 for classes
    static final ArchRule noJakartaTransactionClasses = noClasses()
        .should().beAnnotatedWith(jakarta.transaction.Transactional.class);

    @ArchTest // test rule 2 for methods
    static final ArchRule noJakartaTransactionMethods = noMethods()
        .should().beAnnotatedWith(jakarta.transaction.Transactional.class);
}

我必须编写 4 个测试,因为我需要对类和方法进行单独的测试。有没有一种方法可以使其更加简洁并编写适用于类或方法的单个测试?

java archunit
1个回答
0
投票

ArchUnit 允许通过利用 Members() 来定位类中的字段和方法来组合类和方法规则

你可以尝试一次吗

import com.tngtech.archunit.junit.ArchTest;
import com.tngtech.archunit.lang.ArchRule;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import jakarta.transaction.Transactional as JakartaTransactional;

import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.*;

class TransactionRules {

    @ArchTest // Combined rule for both classes and methods for @Transactional
    static final ArchRule transactionalServices = members()
        .that().areAnnotatedWith(Transactional.class)
        .or().areDeclaredInClassesThat().areAnnotatedWith(Transactional.class)
        .should().beDeclaredInClassesThat().areAnnotatedWith(Service.class)
        .andShould().beAnnotatedWith(Service.class);

    @ArchTest // Combined rule for both classes and methods for @jakarta.transaction.Transactional
    static final ArchRule noJakartaTransactional = members()
        .that().areAnnotatedWith(JakartaTransactional.class)
        .or().areDeclaredInClassesThat().areAnnotatedWith(JakartaTransactional.class)
        .should().notBeAnnotatedWith(JakartaTransactional.class)
        .andShould().notBeDeclaredInClassesThat().areAnnotatedWith(JakartaTransactional.class);
}
© www.soinside.com 2019 - 2024. All rights reserved.