有没有办法在使用Spring或Spring Boot的JUnit测试中使用Autowired构造函数?

时间:2018-10-15 08:56:48

标签: java spring junit integration-testing autowired

假设我有一个包含几个Spring bean的测试配置,这些配置实际上是被模拟的,我想在JUnit测试套件中指定这些模拟的行为。

@Profile("TestProfile")
@Configuration
@EnableTransactionManagement
@ComponentScan(basePackages = {
        "some.cool.package.*"})
public class IntegrationTestConfiguration {

    @Bean
    @Primary
    public Cool cool() {
        return Mockito.mock(Cool.class);
    }
}

// ...

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
@ActiveProfiles("TestProfile")
public class CoolIntegrationTest {

    private final Cool cool;

    @Autowired
    public CoolIntegrationTest(Cool cool) {
        this.cool = cool;
    }

    @Test
    public void testCoolBehavior {
        when(cool.calculateSomeCoolStuff()).thenReturn(42);
        // etc
    }
}

如果运行此测试,我将得到:

java.lang.Exception: Test class should have exactly one public zero-argument constructor

我知道解决方法,例如在测试中使用“自动连接”字段,但是我想知道是否可以在JUnit测试中使用“自动连接”注释?

4 个答案:

答案 0 :(得分:0)

除了args构造函数之外,您还需要另外一个no-args构造函数。尝试添加它,并检查是否仍然发生此异常。

@Autowired
public CoolIntegrationTest(Cool cool) {
        this.cool = cool;
    }

public CoolIntegrationTest() {}

答案 1 :(得分:0)

问题不在于自动装配,而是无参数构造函数。 JUnit测试类应具有一个无参数的构造函数。要实现您想要做的事情,您应该执行以下操作:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
@ActiveProfiles("TestProfile")
@ContextConfiguration(classes = {IntegrationTestConfiguration.class})
public class CoolIntegrationTest {

    @Autowired
    private final Cool cool;

    @Test
    public void testCoolBehavior {
        when(cool.calculateSomeCoolStuff()).thenReturn(42);
        // etc
    }
}

contextConfiguration批注告诉spring用于测试的配置,并且自动装配字段而不是构造函数将允许您测试spring bean。

答案 2 :(得分:0)

要使用Spring运行测试,您必须添加@RunWith(SpringRunner.class)并确保将您的类添加到类路径中。有几种方法可以做到这一点。即 将类添加到MVC配置@WebMvcTest({Class1.class, Class2.class})或使用@ContextConfiguration

但是我看到了您的代码,我想使用@Mock@MockBean模拟您的bean会更容易。这样会容易得多。

答案 3 :(得分:0)

JUnit要求测试用例具有一个无参数的构造函数,因此,由于您没有该构造函数,因此在接线过程之前会发生异常。

因此在这种情况下,构造函数自动装配不起作用。

那该怎么办?

有很多方法:

最简单的一种方法(因为有春天)是利用@MockBean注释:

@RunWith(SpringRunner.class)
@SpringBootTest
 ....
class MyTest {

   @MockBean
   private Cool cool;

   @Test
   void testMe() {
      assert(cool!= null); // its a mock actually
   }
}