Java 弹簧启动单元测试

Java 弹簧启动单元测试,java,junit,spring-boot,Java,Junit,Spring Boot,我不熟悉弹簧靴。需要一些建议吗 这是我的单元测试课 @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = DemoApplication.class) public class EmployeeRepositoryTest { @Autowired protected EmployeeRepository employeeRepository; @Test public void

我不熟悉弹簧靴。需要一些建议吗 这是我的单元测试课

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = DemoApplication.class)
public class EmployeeRepositoryTest {

@Autowired
protected EmployeeRepository employeeRepository;


@Test
public void insertEmploee(){

    Employee employee = new Employee();

    employee.setEmpName("Azad");
    employee.setEmpDesignation("Engg");
    employee.setEmpSalary(12.5f);

    employeeRepository.save(employee);

}
}

当我运行它时,我得到异常

java.lang.NoSuchMethodError: org.springframework.core.annotation.AnnotatedElementUtils.findMergedAnnotationAttributes(Ljava/lang/reflect/AnnotatedElement;Ljava/lang/String;ZZ)Lorg/springframework/core/annotation/AnnotationAttributes;

at org.springframework.test.util.MetaAnnotationUtils$AnnotationDescriptor.<init>(MetaAnnotationUtils.java:290)
at org.springframework.test.util.MetaAnnotationUtils$UntypedAnnotationDescriptor.<init>(MetaAnnotationUtils.java:365)
at org.springframework.test.util.MetaAnnotationUtils$UntypedAnnotationDescriptor.<init>(MetaAnnotationUtils.java:360)
at org.springframework.test.util.MetaAnnotationUtils.findAnnotationDescriptorForTypes(MetaAnnotationUtils.java:191)
at org.springframework.test.util.MetaAnnotationUtils.findAnnotationDescriptorForTypes(MetaAnnotationUtils.java:198)
at 
java.lang.NoSuchMethodError:org.springframework.core.annotation.AnnotatedElementUtils.findMergedAnnotationAttributes(Ljava/lang/reflect/AnnotatedElement;Ljava/lang/String;ZZ)Lorg/springframework/core/annotation/AnnotationAttributes;
位于org.springframework.test.util.MetaAnnotationUtils$AnnotationDescriptor。(MetaAnnotationUtils.java:290)
位于org.springframework.test.util.MetaAnnotationUtils$UntypedAnnotationDescriptor。(MetaAnnotationUtils.java:365)
位于org.springframework.test.util.MetaAnnotationUtils$UntypedAnnotationDescriptor。(MetaAnnotationUtils.java:360)
位于org.springframework.test.util.MetaAnnotationUtils.findAnnotationDescriptorForTypes(MetaAnnotationUtils.java:191)
位于org.springframework.test.util.MetaAnnotationUtils.findAnnotationDescriptorForTypes(MetaAnnotationUtils.java:198)
在

进程结束,退出代码为-1

您的问题似乎已经解决了(混合了Spring依赖项版本),但让我扩展一下@g00glen00b关于如何编写单元测试的评论

确保您的
pom.xml
中存在以下依赖项:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>

例如,可以找到关于使用Mockito的好帖子。

EmployeeRepository
上使用
@Autowired
我们可以使用
@MockBean
因为我们正在编写单元测试,我们不需要处理真实数据,我们只需要验证函数是否正常工作。检查下面的代码

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = Main.class)//main springboot class
@WebAppConfiguration
public abstract class AbstractBaseTest {
   protected MockMvc mvc;
   @Autowired
   WebApplicationContext webApplicationContext;

   protected void setUp() {
      mvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
   }

}    

public class EmployeeRepositoryTest extends AbstractBaseTest{

@MockBean
protected EmployeeRepository employeeRepository;

 @Override
   @Before
   public void setUp() {
      super.setUp();
   }

@Test
public void insertEmploee(){

    Employee employee = new Employee();

    employee.setEmpName("Azad");
    employee.setEmpDesignation("Engg");
    employee.setEmpSalary(12.5f);

       Mockito.doNothing().when(employeeRepository).save(Mockito.any(Employee.class));
       employeeRepository.save(employee);
       Mockito.verify(employeeRepository, Mockito.times(1)).save(employee);

}
}

看起来您的依赖项有问题(可能您混合了一些Spring版本)。您能否提供您的依赖项(如果您使用的是maven或等效的gradle文件,则为pom.xml)?@MikeBoddin问题已经解决。您是对的,顺便说一句,如果您在测试中启动Spring上下文,它基本上不再被视为单元测试。@luboskrnac我想知道更多细节。虽然命名/标题是错误的,但这更像是一个集成测试,而不是实际的单元测试。对于单元测试(当您只需要测试某段代码时),使用
SpringJUnit4ClassRunner
runner可能不是一个好主意,因为它启动整个应用程序,并且比不使用runner慢得多。在本例中,您可能要检查记录是否在数据库上创建,在本例中,您正在编写集成测试。无法实例化名为“employeeRepository”的InjectMock字段。您尚未在字段声明中提供实例,因此我尝试构造实例。但是,我失败了,因为“EmployeeRepository”类型是一个接口。InjectMocks的正确用法示例:InjectMocks服务=新服务();提供模拟服务;我不知道这是一个SpringJPA存储库(尽管从名称上看应该很明显)。在这种情况下,它实际上是一个集成测试,您最初的尝试是正确的。我的帖子主要适用于需要实例化的类。它可能会帮助您进行一些其他的单元测试。Spring存储库不必经过单元测试(它们已经在Spring中了)。您只能使用它们执行集成测试。希望它有意义这可能是一本有用的读物:
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = Main.class)//main springboot class
@WebAppConfiguration
public abstract class AbstractBaseTest {
   protected MockMvc mvc;
   @Autowired
   WebApplicationContext webApplicationContext;

   protected void setUp() {
      mvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
   }

}    

public class EmployeeRepositoryTest extends AbstractBaseTest{

@MockBean
protected EmployeeRepository employeeRepository;

 @Override
   @Before
   public void setUp() {
      super.setUp();
   }

@Test
public void insertEmploee(){

    Employee employee = new Employee();

    employee.setEmpName("Azad");
    employee.setEmpDesignation("Engg");
    employee.setEmpSalary(12.5f);

       Mockito.doNothing().when(employeeRepository).save(Mockito.any(Employee.class));
       employeeRepository.save(employee);
       Mockito.verify(employeeRepository, Mockito.times(1)).save(employee);

}
}