java 如何用Spring Autowire编写JUnit测试?

mlnl4t2r  于 2022-12-28  发布在  Java
关注(0)|答案(8)|浏览(162)

下面是我使用的文件:

组件.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>

服务实现java

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

    @Autowired
    private MyDAO myDAO;

    public void getData() {...}    
}

服务实现测试.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]
x8goxv8g

x8goxv8g1#

确保你导入了正确的软件包。如果我没记错的话,有两个不同的软件包可以自动安装。应该是:第一个月
我也觉得这很奇怪:

@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());

    }
sulc1iza

sulc1iza2#

我使用了两个测试类注解:@RunWith(SpringRunner.class)@SpringBootTest。示例:

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

    @Autowired
    private ProtocolTransactionService protocolTransactionService;
}

@SpringBootTest加载整个上下文,这在我的例子中是可以的。

1l5u6lss

1l5u6lss3#

使用Autowired和bean模拟(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");
    }
}
lp0sw83n

lp0sw83n4#

至少在Spring2.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);
    }
}
lrl1mhuk

lrl1mhuk5#

对于Spring 5.x和JUnit 5,编写单元测试是完全不同的。
我们必须使用@ExtendWith来注册Spring扩展(SpringExtension),这将使Spring发挥作用,激活应用程序上下文的 * 部分 *(示例化和管理来自 * 选定 * 配置类的bean)。
注意,这与@SpringBootTest的效果不同,@SpringBootTest加载了完整的应用程序上下文(IMHO不能被视为单元测试)。
例如,让我们创建一个配置类FooConfig,它生成一个名为foo1的bean:

@Configuration
public class FooConfig
{
    @Bean
    public String foo1() { return "Foo1"; }
}

现在,让我们编写一个注入foo1的JUnit 5测试用例:

import static org.junit.jupiter.api.Assertions.*;
// ... more imports ...

@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = {
    helloworld.config.FooConfig.class,
})
class FooTests
{
    @BeforeAll
    static void setUpBeforeClass() throws Exception {}

    @AfterAll
    static void tearDownAfterClass() throws Exception {}

    @BeforeEach
    void setUp() throws Exception {}

    @AfterEach
    void tearDown() throws Exception {}
    
    @Autowired
    private String foo1;
    
    @Test
    void test()
    {
        assertNotNull(foo1);
        System.err.println(foo1);
    }
}
qacovj5a

qacovj5a6#

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

idfiyjo8

idfiyjo87#

您应该在您的测试资源文件夹中创建另一个XML-spring配置文件,或者只是复制旧的配置文件,看起来不错,但是如果您尝试启动一个Web上下文来测试微服务,只需将以下代码作为您的主测试类并从其继承:

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

zz2j4svz8#

可以使用@Import注解,它比@ComponentScan注解可读性更强,也更短。

import org.springframework.context.annotation.Import;

@Import(value = {MyService.class, MyInjectedService.class})
public class JUnitTest {
    @Autowired
    private MyService service;

    // ...
}

相关问题