春季批测试用例

问题描述 投票:0回答:1

我对Spring批处理和测试用例非常陌生,我创建了一个示例程序,该程序从表中获取数据,将名称更新为大写,然后保存回数据库中。

处理器

import com.example.demo.demoWeb.model.User;
import org.springframework.batch.item.ItemProcessor;
import org.springframework.stereotype.Component;
@Component
public class Processor implements ItemProcessor<User, User> {
    @Override
    public User process(User user) throws Exception {
        System.out.println("Processor.process user = " + user);
        user.setName(user.getName().toUpperCase());
        return user;
    }
}

作家

import com.example.demo.demoWeb.model.User;
import com.example.demo.demoWeb.repository.UserRepository;
import org.springframework.batch.item.ItemWriter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
@Component
public class Writer implements ItemWriter<User> {
    @Autowired
    UserRepository userRepository;

    @Override
    public void write(List<? extends User> users) throws Exception {
        System.out.println("Writer.write users = " + users);
        userRepository.saveAll(users);
    }
}

批处理配置

import com.example.demo.demoWeb.model.User;
import org.apache.tomcat.dbcp.dbcp2.BasicDataSource;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.launch.support.RunIdIncrementer;
import org.springframework.batch.item.ItemProcessor;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.database.JdbcPagingItemReader;
import org.springframework.batch.item.database.Order;
import org.springframework.batch.item.database.PagingQueryProvider;
import org.springframework.batch.item.database.support.H2PagingQueryProvider;
import org.springframework.batch.item.database.support.MySqlPagingQueryProvider;
import org.springframework.batch.item.file.LineMapper;
import org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper;
import org.springframework.batch.item.file.mapping.DefaultLineMapper;
import org.springframework.batch.item.file.transform.DelimitedLineTokenizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;
@Configuration
@EnableBatchProcessing
public class SpringBatchConfig {
    @Bean
    public Job job(JobBuilderFactory jobBuilderFactory, StepBuilderFactory stepBuilderFactory, ItemReader<User> itemReader, ItemProcessor<User, User> itemProcessor, ItemWriter<User> itemWriter) {
        Step step = stepBuilderFactory.get("ETL-LOAD_FILE")
                .<User, User>chunk(1)
                .reader(itemReader)
                .processor(itemProcessor)
                .writer(itemWriter)
                .build();
        return jobBuilderFactory
                .get("ETL-JOB")
                .incrementer(new RunIdIncrementer())
                .start(step).build();
    }
    @Bean
    ItemReader<User> itemReader(DataSource dataSource) {
        JdbcPagingItemReader<User> databaseReader = new JdbcPagingItemReader<>();
        databaseReader.setDataSource(dataSource);
        databaseReader.setPageSize(1);
        PagingQueryProvider queryProvider = createQueryProvider();
        databaseReader.setQueryProvider(queryProvider);
        databaseReader.setRowMapper(new BeanPropertyRowMapper<>(User.class));
        return databaseReader;
    }
    private PagingQueryProvider createQueryProvider() {
        MySqlPagingQueryProvider queryProvider = new MySqlPagingQueryProvider();
        queryProvider.setSelectClause("SELECT id, dept, name, salary");
        queryProvider.setFromClause("FROM USER");
        queryProvider.setSortKeys(sortByEmailAddressAsc());
        return queryProvider;
    }
    private Map<String, Order> sortByEmailAddressAsc() {
        Map<String, Order> sortConfiguration = new HashMap<>();
        sortConfiguration.put("salary", Order.ASCENDING);
        return sortConfiguration;
    }
    private LineMapper<User> lineMapper() {
        DefaultLineMapper<User> defaultLineMapper = new DefaultLineMapper<>();
        DelimitedLineTokenizer delimitedLineTokenizer = new DelimitedLineTokenizer();
        delimitedLineTokenizer.setDelimiter(",");
        delimitedLineTokenizer.setStrict(false);
        delimitedLineTokenizer.setNames("id", "name", "dept", "salary");
        BeanWrapperFieldSetMapper<User> beanWrapperFieldSetMapper = new BeanWrapperFieldSetMapper<>();
        beanWrapperFieldSetMapper.setTargetType(User.class);
        defaultLineMapper.setLineTokenizer(delimitedLineTokenizer);
        defaultLineMapper.setFieldSetMapper(beanWrapperFieldSetMapper);
        return defaultLineMapper;
    }
    @Bean
    public DataSource dataSource() {
        BasicDataSource dataSource = new BasicDataSource();
        dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost/Apple");
        dataSource.setUsername("root");
        dataSource.setPassword("root");
        return dataSource;
    }
}

型号

import javax.persistence.Entity;
import javax.persistence.Id;
import java.util.Objects;    
@Entity
public class User {
    @Id
    private Integer id;
    private String name;
    private String dept;
    private Integer salary;    
    public User(Integer id, String name, String dept, Integer salary) {
        this.id = id;
        this.name = name;
        this.dept = dept;
        this.salary = salary;
    }    
    public User() {
    }    
    public Integer getId() {
        return id;
    }    
    public void setId(Integer id) {
        this.id = id;
    }    
    public String getName() {
        return name;
    }    
    public void setName(String name) {
        this.name = name;
    }    
    public String getDept() {
        return dept;
    }    
    public void setDept(String dept) {
        this.dept = dept;
    }    
    public Integer getSalary() {
        return salary;
    }    
    public void setSalary(Integer salary) {
        this.salary = salary;
    }    
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        User user = (User) o;
        return id.equals(user.id);
    }    
    @Override
    public int hashCode() {
        return Objects.hash(id);
    }    
    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", dept='" + dept + '\'' +
                ", salary=" + salary +
                '}';
    }
}

存储库

import com.example.demo.demoWeb.model.User;
import org.springframework.data.jpa.repository.JpaRepository;
public interface UserRepository extends JpaRepository<User, Integer> {
}

主要应用

import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.JobParametersBuilder;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
@EnableScheduling
@SpringBootApplication
public class DemoWebApplication {
    @Autowired
    JobLauncher jobLauncher;
    @Autowired
    Job job;
    public static void main(String[] args) {
        SpringApplication.run(DemoWebApplication.class, args);
    }
    @Scheduled(cron = "0 */1 * * * ?")
    public void perform() throws Exception {
        JobParameters params = new JobParametersBuilder()
                .addString("JobID", String.valueOf(System.currentTimeMillis()))
                .toJobParameters();
        jobLauncher.run(job, params);
    }
}

成绩文件

plugins {
    id 'org.springframework.boot' version '2.3.0.RELEASE'
    id 'io.spring.dependency-management' version '1.0.9.RELEASE'
    id 'java'
}    
group = 'com.example.demo'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '14'    
repositories {
    mavenCentral()
}    
dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
    implementation 'org.springframework.boot:spring-boot-starter-batch'
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
    implementation 'org.springframework.boot:spring-boot-starter-test'
    implementation 'org.springframework.batch:spring-batch-test'
    implementation 'mysql:mysql-connector-java'
    compile 'org.apache.tomcat:tomcat-dbcp:9.0.1'
}
test {
    useJUnitPlatform()
}

我已经浏览了Google的4-5页,但仍然找不到带有测试用例的Spring Batch的有效示例。大多数示例过于抽象,以至于我无法与之联系。

到目前为止,我想到了这个。但是它失败了,我不知道这是怎么回事。

import com.example.demo.demoWeb.config.SpringBatchConfig;
import org.junit.After;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.batch.core.BatchStatus;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.test.JobLauncherTestUtils;
import org.springframework.batch.test.JobRepositoryTestUtils;
import org.springframework.batch.test.context.SpringBatchTest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestExecutionListeners;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
import org.springframework.test.context.support.DirtiesContextTestExecutionListener;
import static org.junit.Assert.assertEquals;
@RunWith(SpringRunner.class)
@SpringBatchTest
@EnableAutoConfiguration
@ContextConfiguration(classes = {SpringBatchConfig.class})
@TestExecutionListeners({DependencyInjectionTestExecutionListener.class,
        DirtiesContextTestExecutionListener.class})
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
public class DemoWebApplicationTest {
    @Autowired
    private JobLauncherTestUtils jobLauncherTestUtils;
    @Autowired
    private JobRepositoryTestUtils jobRepositoryTestUtils;
    @After
    public void cleanUp() {
        jobRepositoryTestUtils.removeJobExecutions();
    }
    @Test
    public void launchJob() throws Exception {
        //testing a job
        JobExecution jobExecution = jobLauncherTestUtils.launchJob();
        //Testing a individual step
        //JobExecution jobExecution = jobLauncherTestUtils.launchStep("step1");
        assertEquals(BatchStatus.COMPLETED, jobExecution.getStatus());
    }
}

我知道JUnit测试用例,但是关于spring batch却一无所知。请指导我如何编写春季批测试案例。

spring-boot spring-batch spring-test
1个回答
1
投票

很难说到底是什么问题。但是,您正在应用程序中使用Spring Boot。您可以从@SpringBootTest替换注释@ContextConfiguration中受益。

Spring Boot提供了一个@SpringBootTest批注,可以将其用作标准弹簧测试@ContextConfiguration的替代方法需要Spring Boot功能时添加注释。

尝试一下:

@SpringBatchTest
@SpringBootTest
@RunWith(SpringRunner.class)
public class DemoWebApplicationTest {
    @Autowired
    private JobLauncherTestUtils jobLauncherTestUtils;
    @Autowired
    private JobRepositoryTestUtils jobRepositoryTestUtils;
    @After
    public void cleanUp() {
        jobRepositoryTestUtils.removeJobExecutions();
    }
    @Test
    public void launchJob() throws Exception {
        //testing a job
        JobExecution jobExecution = jobLauncherTestUtils.launchJob();
        //Testing a individual step
        //JobExecution jobExecution = jobLauncherTestUtils.launchStep("step1");
        assertEquals(BatchStatus.COMPLETED, jobExecution.getStatus());
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.