春季云流处理器单元测试-@Autowire无法正常工作

时间:2019-12-10 15:36:13

标签: spring junit autowired spring-cloud-stream spring-cloud-dataflow

我正在尝试编写一个 Spring云流处理器类,该类通过使用@StreamListener(Processor.INPUT)批注将 XML 引入。

然后处理器提取较小的 XML 消息,并通过this.processor.output().send(message);将其发送到输出 我尚未将其部署到 dataflow ,因为我想使用 junit 对其进行测试。当我使用 junit 运行此程序时,似乎无法实例化我的Processor对象。

我尝试使用@Autowired,这是我在may示例中看到的方法,但是我似乎无法使其正常工作。任何想法,将不胜感激。

我的代码在下面。

package io.spring.dataflow.sample.usagecostprocessor;

import java.io.File;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.stream.annotation.EnableBinding;
import org.springframework.cloud.stream.annotation.StreamListener;
import org.springframework.cloud.stream.messaging.Processor;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Component;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;

import lombok.AllArgsConstructor;

@AllArgsConstructor
@EnableBinding(Processor.class)
public class REDACTXMLSplitter {


    private Processor processor;

    //@Autowired
    //private SendingBean sendingBean;

    @SuppressWarnings("unchecked")
    @StreamListener(Processor.INPUT)
    public void parseForREDACTApplications(String redactXML) {
        InputSource doc = new InputSource( new StringReader( redactXML ) );

        try
         {

                DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
                DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();

                DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
                factory.setNamespaceAware(true); // never forget this!

                XPathFactory xfactory = XPathFactory.newInstance();
                XPath xpath = xfactory.newXPath();

                String xpathQuery = "//REDACT/Application";

                xpath = xfactory.newXPath();
                XPathExpression query = xpath.compile(xpathQuery);
                NodeList productNodesFiltered = (NodeList) query.evaluate(doc, XPathConstants.NODESET);

                for (int i=0; i<productNodesFiltered.getLength(); ++i)
                {

                    Document suppXml = dBuilder.newDocument();

                    //we have to recreate the root node <products>
                    Element root = suppXml.createElement("REDACT"); 

                    Node productNode = productNodesFiltered.item(i);

                    //we append a product (cloned) to the new file
                    Node clonedNode = productNode.cloneNode(true);
                    suppXml.adoptNode(clonedNode); //We adopt the orphan :)
                    root.appendChild(clonedNode);

                    suppXml.appendChild(root);


                    //write out files
                    //At the end, we save the file XML on disk
//                      TransformerFactory transformerFactory = TransformerFactory.newInstance();
//                      Transformer transformer = transformerFactory.newTransformer();
//                      transformer.setOutputProperty(OutputKeys.INDENT, "yes");
//                      DOMSource source = new DOMSource(suppXml);
//                      StreamResult result =  new StreamResult(new File("test_" + i + ".xml"));
//                      transformer.transform(source, result);

                    TransformerFactory tf = TransformerFactory.newInstance();
                    Transformer transformer = tf.newTransformer();
                    transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
                    StringWriter writer = new StringWriter();
                    transformer.transform(new DOMSource(suppXml), new StreamResult(writer));
                    String output = writer.getBuffer().toString().replaceAll("\n|\r", "");

                    System.out.println(output);

                    Message<String> message = (Message<String>) suppXml;
                    this.processor.output().send(message);
                }

            }
         catch (XPathExpressionException | ParserConfigurationException | TransformerException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

package io.spring.dataflow.sample.usagecostprocessor;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;


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

package io.spring.dataflow.sample.usagecostprocessor;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.stream.messaging.Processor;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.util.ResourceUtils;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@DirtiesContext
public class MAIPXMLSplitterApplicationTests {


    @Autowired
    private Processor myProcessor;


    @Test
    public void contextLoads() {
    }

    @Test
    public void parseXML() {
            try {
                String cmErrorPayloadXML = readFile(ResourceUtils.getFile(this.getClass().getResource("/XMLSamples/REDACTApplicationXMLSamples/redact.xml")));
                REDACTXMLSplitter redactXMLSplitter = new REDACTXMLSplitter(myProcessor);
                redactXMLSplitter.parseForREDACTApplications(cmErrorPayloadXML);
            } catch (IOException e) {
                e.printStackTrace();
            }
    }


      public String readFile(File file) {
            StringBuffer stringBuffer = new StringBuffer();
            if (file.exists())
                try {
                    //read data from file
                    FileInputStream fileInputStream = new FileInputStream(file);
                    int c;
                    while ((c = fileInputStream.read()) != -1){
                        stringBuffer.append((char) c);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            return stringBuffer.toString();
        }

}

更新

我尝试过,但是myProcessor仍然为空

package io.spring.dataflow.sample.usagecostprocessor;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.stream.annotation.EnableBinding;
import org.springframework.cloud.stream.messaging.Processor;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.util.ResourceUtils;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

@RunWith(SpringRunner.class)
@SpringBootTest(classes = MAIPXMLSplitterApplicationTests.TestProcessor.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class MAIPXMLSplitterApplicationTests {


    @Autowired
    private Processor myProcessor;

    @Test
    public void contextLoads() {
    }

    @Test
    public void parseXML() {
            try {
                String cmErrorPayloadXML = readFile(ResourceUtils.getFile(this.getClass().getResource("/XMLSamples/MAIPApplicationXMLSamples/354_20191126_MAIP.xml")));
                MAIPXMLSplitter maipXMLSplitter = new MAIPXMLSplitter(myProcessor);
                maipXMLSplitter.parseForMAIPApplications(cmErrorPayloadXML);
            } catch (IOException e) {
                e.printStackTrace();
            }
    }


      public String readFile(File file) {
            StringBuffer stringBuffer = new StringBuffer();
            if (file.exists())
                try {
                    //read data from file
                    FileInputStream fileInputStream = new FileInputStream(file);
                    int c;
                    while ((c = fileInputStream.read()) != -1){
                        stringBuffer.append((char) c);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            return stringBuffer.toString();
        }

        @EnableBinding(Processor.class)
        @EnableAutoConfiguration
        public static class TestProcessor {

        }

}

1 个答案:

答案 0 :(得分:0)

您需要在Test类使用的配置类之一中拥有@EnableBinding(Processor.class)

通常,您可以有一个简单的@Configuration子类,并将其包含在@SpringBootTest类列表中。您可以看到一个示例here