junit使用stub进行单元测试

版权声明:凭栏处,潇潇雨歇。 https://blog.csdn.net/IndexMan/article/details/85163206

stub是代码的一部分,我们要对某一方法做单元测试时,可能涉及到调用第三方web服务。假如当前该服务不存在或不可用咋办?好办,写一段stub代码替代它。

stub 技术就是把某一部分代码与环境隔离起来(比如,通过替换 Web服务器、文件系统、数据库等手段)从而进行单元测试的。

下面演示一个例子,利用jetty编写相关的stub充当web服务器,返回适当内容。

环境: idea + spring boot + jetty

关于jetty服务器,对比tomcat更轻量级,可轻松嵌入java代码启动它。

如何在项目中启动一个jetty服务器?

package com.lhy.junitkaifa.stubs;

import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.server.handler.ResourceHandler;

/**
 * @author xusucheng
 * @create 2018-12-20
 **/
public class JettySample {
    public static void main(String[] args) throws Exception {
        Server server = new Server( 8081 );

        ContextHandler context = new ContextHandler(server,"/");
        //默认为项目根目录
        context.setResourceBase(".");
        context.setHandler(new ResourceHandler());

        server.setStopAtShutdown( true );
        server.start();
    }
}

请求:http://localhost:8081

编写一个获取url内容的工具方法叫WebClient

package com.lhy.junitkaifa.stubs;

import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

/**
 * 读取指定URL内容
 * @author xusucheng
 * @create 2018-12-20
 **/
public class WebClient {
    public String getContent( URL url )
    {
        StringBuffer content = new StringBuffer();
        try
        {
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setDoInput( true );
            InputStream is = connection.getInputStream();
            byte[] buffer = new byte[2048];
            int count;
            while ( -1 != ( count = is.read( buffer ) ) )
            {
                content.append( new String( buffer, 0, count ) );
            }
        }
        catch ( IOException e )
        {
            return null;
        }
        return content.toString();
    }

    public static void main(String[] args) throws Exception{
        WebClient wc = new WebClient();
        String content = wc.getContent(new URL("http://www.baidu.com/"));

        System.out.println(content);
    }
}

编写测试类TestWebClient

package com.lhy.junitkaifa.stubs;

import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.AbstractHandler;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.server.handler.HandlerList;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.util.ByteArrayISO8859Writer;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.springframework.http.HttpHeaders;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URL;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;

/**
 * @author xusucheng
 * @create 2018-12-20
 **/
public class TestWebClient {
    private WebClient client = new WebClient();
    private static final int PORT=8081;

    @BeforeClass
    public static void setUp() throws Exception{
        System.out.println("====================Befor Class=====================");

        Server server = new Server(PORT);
        TestWebClient t = new TestWebClient();

        ContextHandler contentOkContext = new ContextHandler(server,"/testGetContentOk");
        contentOkContext.setHandler(t.new TestGetContentOkHandler());

        ContextHandler contentErrorContext = new ContextHandler(server,"/testGetContentError");
        contentErrorContext.setHandler(t.new TestGetContentServerErrorHandler());

        ContextHandler contentNotFoundContext = new ContextHandler(server,"/testGetContentNotFound");
        contentNotFoundContext.setHandler(t.new TestGetContentNotFoundHandler());

        HandlerList handlers = new HandlerList();
        handlers.setHandlers(new Handler[] { contentOkContext, contentErrorContext, contentNotFoundContext});
        server.setHandler(handlers);

        server.setStopAtShutdown( true );
        server.start();
    }

    @Test
    public void testGetContentOk()
            throws Exception
    {
        String result = client.getContent( new URL( "http://localhost:"+PORT+"/testGetContentOk" ) );
        assertEquals( "It works", result );
    }

    @Test
    public void testGetContentError()
            throws Exception
    {
        String result = client.getContent( new URL( "http://localhost:"+PORT+"/testGetContentError/" ) );
        assertNull( result );
    }

    @Test
    public void testGetContentNotFound()
            throws Exception
    {
        String result = client.getContent( new URL( "http://localhost:"+PORT+"/testGetContentNotFound" ) );
        assertNull( result );
    }

    @AfterClass
    public static void tearDown()
    {
        // Do nothing becuase the Jetty server is configured
        // to stop at shutdown.
        System.out.println("====================After Class=====================");
    }

    /**
     * 正常请求处理器
     */
    private class TestGetContentOkHandler
            extends AbstractHandler
    {

        @Override
        protected void doStart() throws Exception {
            super.doStart();
        }

        @Override
        public void setServer(Server server) {
            super.setServer(server);
        }

        @Override
        public void handle(String s, Request request, HttpServletRequest httpServletRequest, HttpServletResponse response) throws IOException, ServletException {
            System.out.println("======================TestGetContentOkHandler=======================");
            OutputStream out = response.getOutputStream();
            ByteArrayISO8859Writer writer = new ByteArrayISO8859Writer();
            writer.write( "It works" );
            writer.flush();
            response.setIntHeader( HttpHeaders.CONTENT_LENGTH, writer.size() );
            writer.writeTo( out );
            out.flush();
            request.setHandled(true);
        }
    }

    /**
     * 异常请求处理器
     */
    private class TestGetContentServerErrorHandler
            extends AbstractHandler
    {
        @Override
        public void handle(String s, Request request, HttpServletRequest httpServletRequest, HttpServletResponse response) throws IOException, ServletException {
            response.sendError( HttpServletResponse.SC_SERVICE_UNAVAILABLE );
        }
    }

    /**
     * 404处理器
     */
    private class TestGetContentNotFoundHandler
            extends AbstractHandler
    {

        @Override
        public void handle(String s, Request request, HttpServletRequest httpServletRequest, HttpServletResponse response) throws IOException, ServletException {
            response.sendError( HttpServletResponse.SC_NOT_FOUND );
        }
    }
}

直接运行该类,结果为:

猜你喜欢

转载自blog.csdn.net/IndexMan/article/details/85163206