0

I'm using OkHttp MockWebServer to mock the server responses.

I have implemented two tests classes, the first one contains two tests and the second one, one test. The first class works fine, but for the second class, there is an error because the socket server is closed.

The first test class

@RunWith(AndroidJUnit4::class)
class LoginActivityTest : TestCase() {

    private lateinit var server: MockWebServer

    @Before
    override public fun setUp() {
        super.setUp()
        server = MockWebServer()
        server.start()
        ApplicationConstants.APP_BASE_URL = server.url("/localhost/").toString()
    }

    @After
    @Throws(Exception::class)
    public override fun tearDown() {
        server.shutdown()
    }

    @Test
    fun successLogin() {
        //given
        server.enqueue(MockResponse()
                .setResponseCode(200)
                .setBody("{...}")
        )
        //rest of the UI test class
    }

    @Test
    fun testAuthenticationFailed() {
        //given
        server.enqueue(MockResponse()
                .setResponseCode(403)
                .setBody("{...}")
        )
        //Rest of the UI test class

    }

}

The log are correct for the two tests

01-02 09:31:23.100 28693-28740/com.mycompany.app D/OkHttp: --> POST http://localhost:39762/client/index.php/rest/login
01-02 09:31:23.100 28693-28740/com.mycompany.app D/OkHttp: Content-Type: application/x-www-form-urlencoded
01-02 09:31:23.101 28693-28740/com.mycompany.app D/OkHttp: Content-Length: 26
01-02 09:31:23.102 28693-28740/com.mycompany.app D/OkHttp: login=admin&password=admin
01-02 09:31:23.103 28693-28740/com.mycompany.app D/OkHttp: --> END POST (26-byte body)
01-02 09:31:23.119 28693-28742/com.mycompany.app I/MockWebServer: MockWebServer[39762] received request: POST /client/index.php/rest/login HTTP/1.1 and responded: HTTP/1.1 200 OK
01-02 09:31:23.121 28693-28740/com.mycompany.app D/OkHttp: <-- 200 OK http://localhost:39762/client/index.php/rest/login (18ms)

01-02 09:31:28.554 28693-28765/com.mycompany.app D/OkHttp: --> POST http://localhost:52440/Unknown%20Client/index.php/rest/login
01-02 09:31:28.554 28693-28765/com.mycompany.app D/OkHttp: Content-Type: application/x-www-form-urlencoded
01-02 09:31:28.555 28693-28765/com.mycompany.app D/OkHttp: Content-Length: 34
01-02 09:31:28.555 28693-28765/com.mycompany.app D/OkHttp: login=Wrong%20Login&password=admin
01-02 09:31:28.555 28693-28765/com.mycompany.app D/OkHttp: --> END POST (34-byte body)
01-02 09:31:28.571 28693-28767/com.mycompany.app I/MockWebServer: MockWebServer[52440] received request: POST /Unknown%20Client/index.php/rest/login HTTP/1.1 and responded: HTTP/1.1 403 Client Error
01-02 09:31:28.571 28693-28765/com.mycompany.app D/OkHttp: <-- 403 Client Error http://localhost:52440/Unknown%20Client/index.php/rest/login (15ms)
01-02 09:31:28.571 28693-28765/com.mycompany.app D/OkHttp: Content-Length: 33
01-02 09:31:28.571 28693-28765/com.mycompany.app D/OkHttp: {"message": "Forbidden access!"}
01-02 09:31:28.571 28693-28765/com.mycompany.app D/OkHttp: <-- END HTTP (33-byte body)
01-02 09:31:28.574 28693-28693/com.mycompany.app E/LoginActivity: HTTP 403 Client Error

The second class is not working and is called after the first class

@RunWith(AndroidJUnit4::class)
class LoginServiceTest : TestCase() {
    private lateinit var server: MockWebServer
    private lateinit var loginService: LoginService

    @Before
    override public fun setUp() {
        super.setUp()
        server = MockWebServer()
        server.start()
        ApplicationConstants.APP_BASE_URL = server.url("/localhost/").toString()
        loginService = ServiceGenerator.createService(LoginService::class.java)
    }

    @After
    @Throws(Exception::class)
    public override fun tearDown() {
        server.shutdown()
    }

    @Test
    @Throws(Exception::class)
    fun testSuccessResponse() {
        //Given
        server.enqueue(MockResponse()
                .setResponseCode(200)
                .setBody("{...}")
        )

        loginService.login("login", "password").subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(
                        { _ ->
                            Assert.assertTrue(false)
                        },
                        { _ ->
                            Assert.assertTrue(false)
                        }
                )
    }
}

The log file, reason socket closed

01-02 09:31:29.919 28693-28776/com.mycompany.app I/MockWebServer: MockWebServer[59904] starting to accept connections
01-02 09:31:29.924 28693-28765/com.mycompany.app D/OkHttp: --> POST http://localhost:59904/client/index.php/rest/login
01-02 09:31:29.924 28693-28765/com.mycompany.app D/OkHttp: Content-Type: application/x-www-form-urlencoded
01-02 09:31:29.925 28693-28765/com.mycompany.app D/OkHttp: Content-Length: 24
01-02 09:31:29.925 28693-28765/com.mycompany.app D/OkHttp: login=login&password=password
01-02 09:31:29.925 28693-28765/com.mycompany.app D/OkHttp: --> END POST (24-byte body)
01-02 09:31:29.929 28693-28776/com.mycompany.app I/MockWebServer: MockWebServer[59904] done accepting connections: Socket closed
01-02 09:31:29.935 28693-28765/com.mycompany.app D/OkHttp: <-- HTTP FAILED: java.io.IOException: unexpected end of stream on Connection{localhost:59904, proxy=DIRECT hostAddress=localhost/127.0.0.1:59904 cipherSuite=none protocol=http/1.1}
01-02 09:31:29.935 28693-28779/com.mycompany.app I/MockWebServer: MockWebServer[59904] connection from localhost/127.0.0.1 failed: java.net.SocketException: Socket closed
Maurice
  • 2,129
  • 2
  • 25
  • 33
  • Also I look into this question: https://stackoverflow.com/questions/37965558/okhttp-mockwebserver-fails-to-accept-connections-when-restarted. But it's not working for me. If you check the log file, the server has already his specific address for each test. – Maurice Jan 02 '18 at 10:33
  • I'm facing same issue any finding for this? – Sam Apr 01 '19 at 21:41
  • Yes I found the solution, but I will have to go back to an old code. I'll let you know. – Maurice Apr 04 '19 at 07:08
  • 1
    OK I found it, I changed my application implementation, by changing the utility class. I put the constant into the ServiceGenerator, in my LoginService it's called like that: .baseUrl(ServiceGenerator.APP_BASE_URL) for Retrofit creation. ServiceGenerator.APP_BASE_URL = server.url("/localhost/").toString() – Maurice Apr 04 '19 at 07:12

0 Answers0