【问题标题】:Spring Boot Testing @WebMvcTest for a Controller appears to load other controllers in the contextSpring Boot Testing @WebMvcTest for a Controller 似乎在上下文中加载其他控制器
【发布时间】:2017-05-21 14:13:05
【问题描述】:

这是我的 Spring 控制器测试用例

@RunWith(SpringRunner.class)
@WebMvcTest(value = MyController.class)
public class MyControllerTest {

    @MockBean
    private MyService myService;
}

所以这是一个专门针对 MyController 中的方法的单元测试。但是当我运行测试时,Spring 似乎开始实例化 OtherController 及其所有依赖项。

我已尝试将以上内容更新为

@RunWith(SpringRunner.class)
@WebMvcTest(value = MyController.class, excludeFilters = @ComponentScan.Filter(value= OtherController.class, type = FilterType.ANNOTATION))


   public class MyControllerTest {

...
}

但弹簧似乎仍然在连接它。这是 Spring 在我专门运行上述测试时尝试实例化 OtherController 时引发的错误。

2017-01-06 12:09:46.207  WARN 18092 --- [           main] o.s.w.c.s.GenericWebApplicationContext   : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'otherController' defined in file [C:\..OtherController.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'getOtherService' defined in com.my.myApplication: Unsatisfied dependency expressed through method 'getOtherService' parameter 0org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'getOtherService' defined in com.myOrg.MyServiceApplication: Unsatisfied dependency expressed through method 'getPositionService' parameter 0

这可能是什么原因造成的?

【问题讨论】:

  • 我知道已经有一段时间了,你解决了吗?你能显示 MyController 和 OtherController 吗?

标签: java spring unit-testing spring-boot spring-test-mvc


【解决方案1】:

可能是您通过@Componentscan 或类似的方式意外触发了 bean 扫描。

例如,正如this answer 中所解释的,Spring 可能正在检测您的“生产”@SpringBootApplicationApplication 类,以及它带来的所有组件扫描。如果是这样,请确保你用你的“测试”“覆盖”你的“生产”应用程序类......

@SpringBootApplication
public class Application {
    public static void main(String[] args) throws Exception {
        SpringApplication.run(Application.class, args);
    }
}

...在会覆盖“生产”应用程序的位置。

例如,如果您的 IDE 没有被类名冲突弄乱:

"production" -> src/main/java/com/mycompany/Application.java
             -> src/main/java/com/mycompany/controllers/MyController.java
"test"       -> src/test/java/com/mycompany/Application.java
             -> src/test/java/com/mycompany/controllers/MyControllerTest.java

作为替代方案,我还发现在我的情况下这也有效(即将应用程序放在测试控制器文件夹中)

"production" -> src/main/java/com/mycompany/Application.java
             -> src/main/java/com/mycompany/controllers/MyController.java
"test"       -> src/test/java/com/mycompany/controllers/Application.java
             -> src/test/java/com/mycompany/controllers/MyControllerTest.java

【讨论】:

  • 我遇到了同样的问题,但不幸的是,这个解决方案对我不起作用。 @SpringBootApplication 注释带有 @ComponentScan 如果我删除 @ComponentScan 每个测试开始给出 404。
  • 重点不在于阻止 Spring 执行可能需要的 ComponentScan。相反,它是关于让扫描测试目录,而不是生产目录。如果在正确的(测试)基类中检测到@ComponentScan,它将扫描相应文件夹和子文件夹(测试包和子包)中的所有组件。从docs 如果没有定义特定的包,将从声明这个注解的类的包开始扫描。
  • 我的代码中没有@ComponentScan,我创建了另一个更符合我的案例的问题。你介意检查一下吗? stackoverflow.com/questions/64724771/…
  • 您是否尝试将 Application.java 文件的“副本”放在与 /main 平行的完全不同的根文件夹下?这是外卖:Application.java 类可以触发其文件系统下所有类的发现,因此您应该指示 Spring 查看 /main 文件夹树以外的位置(而不是 /test 文件夹树).. .
  • 也许您的测试套件在运行测试时仍在查看 /main 文件夹(以及 /test 文件夹)?如果您从“主”应用程序类中删除@SpringBootApplication,测试是否正常?我知道您说过应用程序不会加载并返回 404,但测试是否正确完成?
猜你喜欢
  • 2018-03-09
  • 2019-01-15
  • 2021-08-02
  • 2021-05-01
  • 1970-01-01
  • 2019-03-23
  • 1970-01-01
  • 1970-01-01
  • 2021-08-16
相关资源
最近更新 更多