Skip to content

GitLab

  • Projects
  • Groups
  • Snippets
  • Help
    • Loading...
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
  • Sign in
N notebook
  • Project overview
    • Project overview
    • Details
    • Activity
    • Releases
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
  • Issues 3
    • Issues 3
    • List
    • Boards
    • Labels
    • Service Desk
    • Milestones
  • Merge requests 0
    • Merge requests 0
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
  • Operations
    • Operations
    • Incidents
    • Environments
  • Packages & Registries
    • Packages & Registries
    • Container Registry
  • Analytics
    • Analytics
    • CI/CD
    • Repository
    • Value Stream
  • Wiki
    • Wiki
  • Members
    • Members
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • Mark Stevens
  • notebook
  • Wiki
  • unit testing

Last edited by Mark Stevens Nov 01, 2017
Page history

unit testing

Unit Testing Network Calls

Using NanoHttpd to isolate network call testing

Simple synchronous network call

    public void testSimpleEcho() throws Exception {
        URL url = new URL("http://localhost:7078/echo/hello_world");
        String responseContents = "";
        HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
        try {
            InputStream in = new BufferedInputStream(urlConnection.getInputStream());
            java.util.Scanner s = new java.util.Scanner(in).useDelimiter("\\A");
            if (s.hasNext()) {
                responseContents = s.next();
            }
        } finally {
            urlConnection.disconnect();
        }
        assertEquals("hello_world", responseContents );
    }

Setup

Gradle

if you are only using nanohttp for testing then use testCompile, otherwise compile

dependencies {
    testCompile 'org.nanohttpd:nanohttpd:2.3.1'
}

Simple MockHttpServer

class MockHttpServer extends NanoHTTPD {

    private Context mContext;
    private Context mTestContext;
    static private Object initlock= new Object();
    
    /**
     * Constructs an HTTP server on given port.
     *
     * @param port
     */
    public MockHttpServer( Context context, int port ) {
        super(port);
        mContext = context;
        mTestContext = null;
    }

    public MockHttpServer(Context context, Context testContext, int port) {
        super(port);
        mContext = context.getApplicationContext();
        mTestContext = testContext;
    }

    @Override
    public Response serve(IHTTPSession session) {
        String route = session.getUri();
        List<String> segs = Uri.parse(route).getPathSegments();
        JSONObject jsonBody = new JSONObject();
        switch(segs.get(0)){
            case "asset":
                if (segs.size()<2 ) {

                    String asset = segs.get(1);
                    try {

                        return newChunkedResponse(
                                Response.Status.OK,
                                "application/octet-stream",
                                mContext.getAssets().open(asset)
                        );

                    } catch (IOException e) {
                        String responseContents = null;
                        responseContents = "<html><body><h1>Request Error</h1>\n";
                        responseContents += "<p>Uri: " + session.getUri() + " </p>";
                        responseContents += "<p>Message: " + e.getMessage() + " </p>";
                        return newFixedLengthResponse(responseContents);
                    }
                }
                break;

            case "echo":
                String msg = segs.size()>1 ? segs.get(1) : "";
                return newFixedLengthResponse(msg);
                //return newFixedLengthResponse(Response.Status.OK, "plain/text", , segs.get(1).length()  );

            case "delay":
                return super.serve(session);

            case "get":
            default:
        }
        // 404: Not Found error
        return super.serve(session);
    }
}

Unit test setup

public class HttpUrlConnectionNetworkTests extends AndroidTestCase {
    NanoHTTPD httpServer;
    Network network;

     @Override
    public void setUp() throws Exception {
        super.setUp();
        RenamingDelegatingContext context = new RenamingDelegatingContext(getContext(), "test_");

        mTestContext = InstrumentationRegistry.getContext();

        httpServer = new MockHttpServer(getContext(), mTestContext, 7078);
        httpServer.start(NanoHTTPD.SOCKET_READ_TIMEOUT, false);

    }

    @Override
    public void tearDown() throws Exception {

        httpServer.stop();
        super.tearDown();
    }
}

serving assets with NanoHttp

Passing in the TestContext allows you to isolate assets to the androidTest apk.

mstevens@lt-mstevens-mac2:bztsitecore$ cd src/androidTest/
mstevens@lt-mstevens-mac2:androidTest$ tree
..
|-- assets
|   |-- soap_GetSiteConfigurationRequest.xml
|   |-- soap_GetSiteConfigurationResponse.xml
|   |-- soap_GetSiteInfoRequest.xml
|   |-- soap_GetSiteInfoResponse.xml
|   |-- soap_GetTabletConfigurationRequest.xml
|   |-- soap_GetTabletConfigurationResponse.xml
|   |-- soap_GetTabletSiteDeviceListRequest.xml
|   |-- soap_GetTabletSiteDeviceListResponse.xml
|   |-- w3_xml_to_json.xml
|   |-- xml_to_json.xml
|   |-- xml_to_json2.xml
|   |-- xslt_identity.xml
|   |-- xslt_outline.xml
|   `-- xslt_strip_comments.xml
`-- java
    `-- com
        `-- buzztime
            |-- net
            |   `-- volley
            |       |-- BTNetVolleyDefaultStackTests.java
            |       |-- BTNetVolleyTests.java
            |       |-- HttpUrlConnectionNetworkTests.java
            |       |-- MockHttpServer.java
            |       `-- SoapRequestTests.java
            |-- site
            |   `-- core
            |       |-- ApplicationTest.java
            |       |-- BTSiteContentProviderTests.java
            |       |-- BTSiteDBHelperTests.java
            |       |-- BTSiteRoutesTests.java
            |       `-- services
            |           `-- BtStartupServiceTests.java
            `-- test
                |-- Repeat.java
                `-- RepeatRule.java

Using a Semaphore to test network responses

Semaphore is an easy way to deal with async calls. A semaphore tracks a permit count, release( ) increments the permit count, aquire( ) decrements the permit if it was non zero.

The pattern is to initialize the Semaphore with no permits. after the async call.. wait with tryAcquire() for a timeout period When the listener is called, it releases a permit and tryAcquire() will return.

    public void testStringRequest() throws Exception {
        final Semaphore semaphore = new Semaphore(0);
        URL url = new URL("http://localhost:7078/echo/hello_world");
        StringRequest stringRequest = new StringRequest(Request.Method.GET, url.toString(),
            new Response.Listener<String>() {
                @Override
                public void onResponse(String response) {
                    assertNotNull(response);
                    assertEquals("hello_world", response);
                    semaphore.release();
                }
            }, new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                }
            });

        stringRequest.setShouldCache(false);
        BTNetVolley.with(getContext())
            .getRequestQueue()
            .add(stringRequest);

        assertTrue(semaphore.tryAcquire(10000, TimeUnit.MILLISECONDS));
    }

Using Future<> to test network requests

Volley supports getting a Future<> object which can be used to inline a network for unit testing

    public void testFutureStringRequest() throws Exception {
        URL url = new URL("http://localhost:7078/echo/hello_world");
        final RequestFuture<String> futureRequest = RequestFuture.newFuture();
        StringRequest stringRequest = new StringRequest(Request.Method.GET, url.toString(),futureRequest, futureRequest);

        stringRequest.setShouldCache(false);
        BTNetVolley.with(getContext())
            .getRequestQueue()
            .add(stringRequest);

        String result = futureRequest.get(5, TimeUnit.SECONDS);
        assertNotNull(result);
        assertEquals("hello_world", result);
    }

Separate Request testing from Response testing

    public void testSoapRequest() throws Exception {

        GetTabletConfigurationRequest gtcr = new GetTabletConfigurationRequest(
            "{340A98F5-F71E-4625-81BC-0A38371213A7}",
            "0000211600069",//serialNumber
            "5ab6b64123925dc", //deviceSerialNumber
            "5ab6b64123925dc", //deviceIdentifier
            "1.0.1.1036 release-keys", //fw disp
            "Buzztime", // fw manu
            "BZT-T101", // fw model
            "5.1.1", // fw os
            22, //fw sdk
            "1.40.00", // sw version
            3560206336l, // data free
            6199967744l // data total
        );
        assertEquals("http://services.buzztime.com/2011/01/ISiteService/GetTabletConfiguration", gtcr.getAction());
        assertEquals("urn:uuid:a6058e8e-279a-4313-a210-58f8deb3d015", gtcr.getMessageId());

        Uri uri = Uri.parse("https://services.dev.buzztime.com/Operations/Constituent/Site/SiteService/SiteService.svc");

        SoapRequest soapRequest = new SoapRequest<>(
            uri.toString(),
            gtcr, GetTabletConfigurationResponse.class, null, null );

        InputStream expectedXmlIn = new BufferedInputStream( mTestContext.getAssets()
            .open("soap_GetTabletConfigurationRequest.xml") );
        String expectedXmlOutline = getXmlTransformed( expectedXmlIn, "xslt_outline.xml");

        String actualXml = new String(soapRequest.getBody());//.replaceAll("\'","\"");
        String actualXmlOutline = getXmlTransformed(actualXml, "xslt_outline.xml");

        System.out.println("ExpectedXML:");
        System.out.println(expectedXmlOutline);
        System.out.println("SerializedXML:");
        System.out.println(actualXmlOutline);

        assertEquals(expectedXmlOutline, actualXmlOutline);

    }
    public void testSoapResponse() throws Exception {

        GetTabletConfigurationResponse response = new GetTabletConfigurationResponse();
        InputStream expectedXmlIn = new BufferedInputStream( mTestContext.getAssets()
            .open("soap_GetTabletConfigurationResponse.xml") );

        XmlPullParser xpp = Xml.newPullParser();
        xpp.setInput(new InputStreamReader( expectedXmlIn ));

        response.deserialize(xpp, response.getClass(), new SoapEnvelopeFilter() );


        assertNotNull(response.mTabletConfiguration);
        TabletConfiguration tc = response.mTabletConfiguration;
        System.out.println("TabletConfiguration:"+tc);

        assertEquals("GMTOffset", "-0800", tc.mGMTOffset);
        assertEquals("RouterSSID", "Buzztime161594909190", tc.mRouterSSID);
        assertEquals("SiteChain", "NONE", tc.mSiteChain);
        assertEquals("SiteLocation.City", "CARLSBAD", tc.mSiteLocation.mAddress.getLocality());
        assertEquals("SiteLocation.Country", "US", tc.mSiteLocation.mAddress.getCountryName());
        assertEquals("SiteLocation.State", "CA", tc.mSiteLocation.mAddress.getAdminArea());
        assertEquals("SiteLocation.Address1", "5966 La Place Court, Suite 100", tc.mSiteLocation.mAddress.getAddressLine(0));
        assertEquals("SiteLocation.Address2", "", tc.mSiteLocation.mAddress.getAddressLine(1));
        assertEquals("SiteLocation.ZipCode", "92008", tc.mSiteLocation.mAddress.getPostalCode());
        assertEquals("SiteLocation.Id", "1097", tc.mSiteLocation.mSiteId);
        assertEquals("SiteLocation.Name", "NTN BUZZTIME 1097", tc.mSiteLocation.mSiteName);
        assertEquals("SitePhone", "(123) 438-7400", tc.mSitePhone);
        assertTrue(tc.mProperties.size() > 0);
        assertEquals("SitePCIPAddress", "172.23.59.193", tc.mSitePCIPAddress);
        assertEquals("SpreadPort", "4803", tc.mSpreadPort);
        assertEquals("StoreNumber", "-1", tc.mStoreNumber);
        assertEquals("NcrAlohaOnlineSiteId", "-1", tc.mNcrAlohaOnlineSiteId);
        assertEquals("NcrCloudConnectCompanyCode", "", tc.mNcrCloudConnectCompanyCode);
        assertEquals("PointOfSaleProvider", "EmptyString", tc.mPointOfSaleProvider);
    }
Clone repository
  • branch code plan
  • build and test configuration
  • build artifact versioning
  • build server instrumented testing
  • build server move
  • bzt16wifi02 releases
  • bzt18uxa02 releases
  • configuration settings and permissions
  • create a repo from cli in gitlab
  • engineering status
  • feature deployment
  • gitlab installation instructions
  • Home
  • ota update and deployment
  • qbert implementation
View All Pages