当前位置: 首页 > 知识库问答 >
问题:

Archunit测试:类只能访问它们实现的接口

广晔
2023-03-14

我有两个包,一个用于接口,一个用于实现。我想将类的访问限制为仅对其实现的接口。说:

package com.interfaces
interface AI {
}

package com.interfaces
interface BI {
}

package com.impls
class A implements AI{
}

package com.impls
class B implements BI{
}

我已经有了一个规则来确保com中的每个类。impls从com实现接口。接口:

ArchRuleDefinition.classes()
        .that().resideInAPackage("com.impls..")
.should().implement(JavaClass.Predicates.resideInAPackage("com.interfaces.."))

现在我需要确保一个类只访问它实现的接口。如果这有帮助的话,我也可以依赖上面示例中的命名约定。我在寻找这样的东西:

ArchRuleDefinition.classes()
        .that().resideInAPackage("com.impls..")
.should().implement(JavaClass.Predicates.resideInAPackage("com.interfaces.."))
.andShould().onlyHaveDependentClassesThat().haveSimpleNameContaining("THE NAME OF THE IMPLEMENTING CLASS")

我们将在任何地方使用接口,实现将被注入(Spring Boot)。但是一个实现不允许访问它没有实现的接口。所以人工智能被允许访问A,但不允许访问B。BI被允许访问B,但不允许访问A!另一方面,接口不仅限于实现。它们将在其他包中使用。

有没有办法重用规则第一部分中的名称,或者在ArchUnit中以另一种方式限制访问?

共有1个答案

袁波
2023-03-14

如果要防止A本身以外的任何类依赖于A等,可以使用

ArchRuleDefinition.classes()
  .that().resideInAPackage("com.impls..")
  .should().implement(JavaClass.Predicates.resideInAPackage("com.interfaces.."))
  .andShould(new ArchCondition<JavaClass>("not have other classes depending on them") {
    @Override
    public void check(JavaClass javaClass, ConditionEvents events) {
      List<JavaClass> otherClassesThatDependOnJavaClass = javaClass.getDirectDependenciesToSelf().stream()
              .map(Dependency::getOriginClass)
              .filter(origin -> !origin.equals(javaClass))  // TODO: inner classes?
              .collect(toList());
      boolean satisfied = otherClassesThatDependOnJavaClass.isEmpty();
      String message = satisfied
              ? "no other classes depend on " + javaClass.getName()
              : otherClassesThatDependOnJavaClass.stream().map(JavaClass::getName)
                .collect(joining(", ", "other classes depend on " + javaClass.getName() + ": ", ""));
      events.add(new SimpleConditionEvent(javaClass, satisfied, message));
    }
  });

如果这是一个用例,那么您可能需要调整过滤器(请参见TODO)以考虑内部类。

。过滤器(原点-

 类似资料:
  • 我编写了我的第一个ArchUnit测试: 这个项目是用Maven构建的,所以类在不同的目录中。 将名称以“tests”或其他东西结尾的类分开是不够的,因为有许多类不是测试,而是只存在于测试类路径中。

  • 我试图测试一个@Controller类,其中有来自POJO的列表。我可以在另一个@RESTController类中使用@Autowired来连接控制器,但在同样的情况下,我不能将其用于测试。 user.java UserContrell3.java 在下一个类中,userresource.java我可以做@autowired 但是,在测试类UserTest.java中。我不能: 提前感谢!

  • 在ArchUnit-Test中,是否有可能从分层测试条件中排除特定的类? 希望我能说清楚...

  • 我有一个Spring应用程序,具有不同的配置文件,例如“开发”和“生产”。我用ArchUnit测试架构。我有像这样的测试 我的包中的类有不同的配置文件。我怎样才能只包含带有Spring概要文件“Production”的类?

  • 我希望编写一个ArchUnit规则,验证服务类(由Spring注释所指出)只使用自己包中的存储库,而不使用其他包中的存储库。 或者,我可以做: 但是,我重复包名3次,我需要为每个包定义这个规则。

  • 出身背景 我有以下情况: 我的测试类实现了 它们都有一个,包含当前测试环境的信息(例如,正在测试的设备) 例如: 这些测试类使用工厂和并行数据提供程序并行执行 这个问题本质上归结为: 如何访问TestNG测试类中的字段? 工具书类 在Java中通过反射访问私有继承字段