Apache Camel在没有数据库配置的情况下模拟处理器

时间:2018-04-13 11:00:38

标签: java spring-boot junit apache-camel

我正在使用Apache Camel + SpringBoot + JDBC。我想对端到端的camel路由进行JUnit测试。我的处理器正在使用Logic进行数据库调用。但是我正在努力删除调用实现测试的数据库调用。我正在努力junit正在工作,但我不知道如何在我的处理器内部模拟JDBC对象。我的处理器中有很多样板代码,因此我不想像在junit示例中那样在junits中复制我的逻辑。请帮我解决这个问题。

Applicaiton.java

@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

MyRouter.java

@Component
public class MyRouter extends RouteBuilder {

    @Autowired
    OrderProcessor processor;

    @Override
    public void configure() throws Exception {
        from("file://src/main/resources/input?delete=true&moveFailed=.error").routeId("route1").convertBodyTo(byte[].class)
                .process(processor).split(simple("${body}")).to("file://src/main/resources/output?fileName=outputfile.txt&fileExist=Append");
    }    
}

OrderProcessor.java

@Component
public class OrderProcessor implements Processor{

    @Autowired
    DataSource dataSource;

    @Autowired
    OrderRepository repository;

    @Override
    public void process(Exchange exchange) throws Exception {
        System.out.println("process starts...");
        byte[] data = exchange.getIn().getBody(byte[].class);
        File dataFile = File.createTempFile("filepre", "bin");
        FileUtils.writeByteArrayToFile(dataFile, data);

        List<String> orders =  new ArrayList<>();

        FileReader fileReader = new FileReader(dataFile);
        BufferedReader bufferedReader = new BufferedReader(fileReader);
        String line;
        while ((line = bufferedReader.readLine()) != null) {
            line = line.substring(line.length()-1);
            orders.add(repository.getOrder(line).toString()+"\n");
        }
        fileReader.close();

        exchange.getIn().setBody(orders);       
    }
}

Order.java

public class Order {
    private int id;
    private int amount;
    // getters and setters
    @Override
    public String toString() {
        return this.id + ":" + this.amount;
    }
}

OrderRepository.java

@Repository
public class OrderRepository {

    @Autowired
    private NamedParameterJdbcTemplate jdbcTemplate;

    public Order getOrder(String id) {

        Map<String, Object> parameters = new HashMap<>();
        parameters.put("refid", id);

        Order extObj = jdbcTemplate.query("select * from world.orders where id = :refid",parameters, rs -> {
            Order innerObj = null;
            if (rs != null) {
                while (rs.next()) {
                    innerObj = new Order();
                    innerObj.setId(rs.getInt("id"));
                    innerObj.setAmount(rs.getInt("amount"));
                }
            }
            return innerObj;
        });
        return extObj;
    }
}

jUnit Class:

public class MyRouterTest extends CamelSpringTestSupport {

    @Override
    protected AbstractApplicationContext createApplicationContext() {
        return new AnnotationConfigApplicationContext();
    }

    @Override
    protected RoutesBuilder createRouteBuilder() throws Exception {
        return new RouteBuilder() {

            @Override
            public void configure() throws Exception {

                from("file://src/test/resources/input?delete=true&moveFailed=.error").routeId("route1")
                        .convertBodyTo(byte[].class).process(exchange -> {
                            Map<String, Integer> mockValues = new HashMap<>();
                            mockValues.put("1", 8);
                            mockValues.put("2", 10);
                            mockValues.put("3", 5);

                            System.out.println("process starts...");
                            byte[] data = exchange.getIn().getBody(byte[].class);
                            File dataFile = File.createTempFile("filepre", "bin");
                            FileUtils.writeByteArrayToFile(dataFile, data);

                            List<String> orders = new ArrayList<>();

                            FileReader fileReader = new FileReader(dataFile);
                            BufferedReader bufferedReader = new BufferedReader(fileReader);
                            String line;
                            while ((line = bufferedReader.readLine()) != null) {
                                line = line.substring(line.length() - 1);
                                Order orderTmp = new Order();
                                orderTmp.setId(Integer.parseInt(line.substring(line.length() - 1)));
                                orderTmp.setAmount(mockValues.get(line.substring(line.length() - 1)).intValue());
                                orders.add(orderTmp.toString() + "\n");
                            }
                            fileReader.close();

                            exchange.getIn().setBody(orders);

                        }).split(simple("${body}"))
                        .to("file://src/test/resources/output?fileName=outputfile.txt&fileExist=Append");
            }
        };
    }

    @Test
    public void checkFileExistsInOutputDirectory() throws InterruptedException {
        Thread.sleep(15000);
        File file = new File("src/test/resources");
        assertTrue(file.isDirectory());
        // Check file content
    }
}

inputfile.txt

line1
line2
line3

outputfile.txt

1:8
2:10
3:5

1 个答案:

答案 0 :(得分:0)

我认为你试图测试太多,处理器逻辑不在MyRouter类的范围内,所以你应该使用mock。处理器的测试应该单独进行。

我的建议:

  • 创建OrderProcessor的模拟
  • 将OrderProcessor的模拟注入MyRouter的实际实现
  • 将MyRouter实例(内置模拟处理器)传递给test
  • 中的createRouteBuilder方法
  • 测试中的呼叫路由

使用Mockito它应该很容易:

public class MyRouterTest extends CamelTestSupport {

@Mock
private OrderProcessor orderProcessor;

@InjectMocks
private MyRouter myRouter;

@Before
public void setUp() throws Exception {
    MockitoAnnotations.initMocks( this );
    super.setUp();   //important

    doAnswer( invocation -> {
        Exchange exchange = invocation.getArgumentAt( 0, Exchange.class );
        //mock processor logic;
        return null;
    } ).when( orderProcessor ).process( any() );
}

@Override
protected RoutesBuilder createRouteBuilder() throws Exception {
    return myRouter;
}

@Test
public void testYourStuff() {
}
}