【问题标题】:How to write JUnit test with Spring Autowire?如何使用 Spring Autowire 编写 JUnit 测试?
【发布时间】:2014-03-19 16:17:29
【问题描述】:

这是我使用的文件:

component.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
    xmlns:jee="http://www.springframework.org/schema/jee"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
         http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
         http://www.springframework.org/schema/context
         http://www.springframework.org/schema/context/spring-context-3.0.xsd 
         http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd">

    <context:component-scan
        base-package="controllers,services,dao,org.springframework.jndi" />
</beans>

ServiceImpl.java

@org.springframework.stereotype.Service
public class ServiceImpl implements MyService {

    @Autowired
    private MyDAO myDAO;

    public void getData() {...}    
}

ServiceImplTest.java

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath*:conf/components.xml")
public class ServiceImplTest{

    @Test
    public void testMyFunction() {...}
}

错误:

16:22:48.753 [main] ERROR o.s.test.context.TestContextManager - Caught exception while allowing TestExecutionListener [org.springframework.test.context.support.DependencyInjectionTestExecutionListener@2092dcdb] to prepare test instance [services.ServiceImplTest@9e1be92]
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'services.ServiceImplTest': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private services.ServiceImpl services.ServiceImplTest.publishedServiceImpl; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [services.ServiceImpl] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:287) ~[spring-beans.jar:3.1.2.RELEASE]

【问题讨论】:

  • 1.您的上下文配置提到了components.xml,但您的文件名为Componet.xml(可能只是本文中的拼写错误) 2. Component.xml 中没有为PublishedReferenceYieldDAO 类定义bean
  • 您还指定了两次组件扫描。一个在 xml 中,一个带有注释。只需要其中一个。
  • @DanTemple 帖子中的拼写错误.. 实际上我的文件名是 component.xml
  • @MystyxMac 感谢您的回答,但我仍然面临同样的问题。

标签: java spring playframework-2.0 junit4


【解决方案1】:

确保您已导入正确的包。如果我没记错的话,自动装配有两个不同的包。应该是:org.springframework.beans.factory.annotation.Autowired;

这对我来说也很奇怪:

@ContextConfiguration("classpath*:conf/components.xml")

这是一个适合我的例子:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "/applicationContext_mock.xml" })
public class OwnerIntegrationTest {

    @Autowired
    OwnerService ownerService;

    @Before
    public void setup() {

        ownerService.cleanList();

    }

    @Test
    public void testOwners() {

        Owner owner = new Owner("Bengt", "Karlsson", "Ankavägen 3");
        owner = ownerService.createOwner(owner);
        assertEquals("Check firstName : ", "Bengt", owner.getFirstName());
        assertTrue("Check that Id exist: ", owner.getId() > 0);

        owner.setLastName("Larsson");
        ownerService.updateOwner(owner);
        owner = ownerService.getOwner(owner.getId());
        assertEquals("Name is changed", "Larsson", owner.getLastName());

    }

【讨论】:

  • 1.正如您提到的导入包。我正在使用相同的 2。我正在使用播放框架,其中文件夹“conf”包含 components.xml,文件夹“app”包含 java 代码。
  • 如何只运行这个测试@PeterParker
  • classpath:conf/components.xml* is global command more stackoverflow.com/tags/glob/info
  • 什么是“/applicationContext_mock.xml”?
【解决方案2】:

我已经为测试类添加了两个注释:@RunWith(SpringRunner.class) 和 @SpringBootTest。 示例:

@RunWith(SpringRunner.class )
@SpringBootTest
public class ProtocolTransactionServiceTest {

    @Autowired
    private ProtocolTransactionService protocolTransactionService;
}

@SpringBootTest 加载整个上下文,在我的情况下这没问题。

【讨论】:

  • 如果你使用这个运行器,你将无法模拟任何 http 对象。
【解决方案3】:

使用 Autowired 和 bean mocking (Mockito) 的 JUnit4 测试:

// JUnit starts with spring context
@RunWith(SpringRunner.class)
// spring loads context configuration from AppConfig class
@ContextConfiguration(classes = AppConfig.class)
// overriding some properties with test values if you need
@TestPropertySource(properties = {
        "spring.someConfigValue=your-test-value",
})
public class PersonServiceTest {

    @MockBean
    private PersonRepository repository;

    @Autowired
    private PersonService personService; // uses PersonRepository    

    @Test
    public void testSomething() {
        // using Mockito
        when(repository.findByName(any())).thenReturn(Collection.emptyList());
        Person person = new Person();
        person.setName(null);

        // when
        boolean found = personService.checkSomething(person);

        // then
        assertTrue(found, "Something is wrong");
    }
}

【讨论】:

    【解决方案4】:

    至少在 Spring 2.1.5 中,XML 文件可以方便地被注释替换。 小猪支持@Sembrano的回答,我有这个。 “看,没有 XML”。

    看来我已经在@ComponentScan 中列出了我需要@Autowired 的所有类

    @RunWith(SpringJUnit4ClassRunner.class)
    @ComponentScan(
        basePackageClasses = {
                OwnerService.class
                })
    @EnableAutoConfiguration
    public class OwnerIntegrationTest {
        
        @Autowired
        OwnerService ownerService;
        
        @Test
        public void testOwnerService() {
           Assert.assertNotNull(ownerService);
        }
    }
    

    【讨论】:

      【解决方案5】:

      我认为在你的代码库中的某个地方是你 @Autowiring 具体类 ServiceImpl 你应该自动装配它的接口(大概是 MyService)。

      【讨论】:

      • 仔细检查任何其他实例以及上下文是否实际查找具有实现类的包。在这些情况下,将 log4j 与 Spring 结合使用并打开 org.springframework 包层次结构的调试会很有帮助 - 您可以看到它正在考虑什么,然后在做什么。
      【解决方案6】:

      你应该在你的测试资源文件夹中创建另一个 XML-spring 配置文件,或者只是复制旧的,它看起来很好,但是如果你试图启动一个 web 上下文来测试一个微服务,只需输入以下代码作为您的主测试类并继承自:

      @WebAppConfiguration
      @RunWith(SpringRunner.class)
      @ContextConfiguration(locations = "classpath*:spring-test-config.xml")
      public abstract class AbstractRestTest {
          @Autowired
          private WebApplicationContext wac;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-07-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-04-02
        • 1970-01-01
        • 2021-08-31
        • 2021-02-03
        相关资源
        最近更新 更多