java.io.StreamCorruptedException for mocked inputstream - unit-testing

I am mocking the socket class and ObjectInputstream class.
Here is a test case which is giving me
java.io.StreamCorruptedException
The test case is as follows:
public void test_tryPush() throws IOException {
ByteArrayInputStream inside = new ByteArrayInputStream("hey".getBytes());
Mockito.when(socket.getInputStream()).thenReturn(inside);
input = new ObjectInputStream(socket.getInputStream());
assertSame(inside, socket.getInputStream());
}
If I do not delcare the input object of ObjectInputStream class the test passes.
But the test above gives the following trace.
Running tests
Test running started
java.io.StreamCorruptedException
at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:2109)
at java.io.ObjectInputStream.<init>(ObjectInputStream.java:372)
at tests.MockingTest.test_tryPush(MockingTest.java:113)
at java.lang.reflect.Method.invokeNative(Native Method)
at android.test.InstrumentationTestCase.runMethod(InstrumentationTestCase.java:214)
at android.test.InstrumentationTestCase.runTest(InstrumentationTestCase.java:199)
at android.test.ActivityInstrumentationTestCase2.runTest(ActivityInstrumentationTestCase2.java:192)
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:190)
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:175)
at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:555)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1661)
Finish
Please can anybody tell me what is going wrong here.
I am trying to mock the client side socket.

Related

How do I inject a mock into my Rails unit test?

I'm trying to figure out how to inject a mock in my test, using Rails 5.1 and minitest. I'm testing this method of the following class ...
module WebsocketClient
class Proxy
...
def connect
#websocket = WebSocket::Client::Simple.connect #websocket_url
I would like to have the line
WebSocket::Client::Simple.connect #websocket_url
return a mock instead of actually trying to connect, so I tried doing this in my unit test
test "connect with open" do
my_worker = my_workers(:one)
assert my_worker.websocket_url.present?, "A pre-condition of this test is that the stratum worker have a websocket URL defined."
proxy = WebsocketClient::Proxy.new( my_worker )
# Stub call to connect
mock_ws = MiniTest::Mock.new
WebSocket::Client::Simple.stub(:connect, my_worker.websocket_url) do
mock_ws
end
# Call the connect method
ws_client = WebsocketClient::Proxy.new(my_worker)
ws_client.connect
However, upon running my test, the mock is not getting executed. Instead the "WebSocket::Client::Simple.connect #websocket_url" is being called as normal. How do I inject my mock in my test?

JdbcTemplate.queryXXX can't get the lastest data

I have a SpringBoot program,There is a problem with one of my junit test case.
SpringBoot version:1.5.9.RELEASE
My code is like this
#Rollback
#Transactional
#RunWith(SpringJUnit4ClassRunner.class)
#SpringBootTest(classes = PreloadJobApplication.class)
#ActiveProfiles("test")
public class PreloadProcessorServiceTest {
#Autowired
PreloadProcessorService testService;
#Autowired
private JdbcTemplate jdbcTemplate;
#Autowired
private JobCalcOrderRepository jobCalcOrderRepository;
#Test
public void my_test_case() {
CreateTestDataWithJdbcTemplate.save(JobPreloadSoEntity.builder()
...
.build(),
jdbcTemplate);
testService.methodToTest();
// List<JobCalcOrderEntity> jobOrders = jobCalcOrderRepository.findAll();
// Assert.assertNotNull(jobOrders);
// Assert.assertEquals(9, jobOrders.size());
long jobCount = jdbcTemplate.queryForObject("select count(*) from Job_Calc_Order", Long.class);
Assert.assertEquals(9, jobCount);
}
}
This code can get right result when run in IDEA with jdbcTemplate or jobCalcOrderRepository. But get zero when run in command line "gradle test"
I have try there ways:
1.Add Thread.sleep(5000) before read data.
2.Try to run queryForObject 3 times, and test the last result.
All failed.who can solve this problem? Thank you.
I have known the reason.
In fact this test case is ok. but the other test case modify testService, and testService.methodToTest() failed to execute a sql, and then all data roll back. I find this reason by test log. I see this in log:
org.springframework.jdbc.BadSqlGrammarException: StatementCallback; bad SQL grammar [UPDATE TestTable SET PROCESS_FLAG = 2 WHERE id> 1 and id<= 101 ]; nested exception is com.microsoft.sqlserver.jdbc.SQLServerException: Invalid object name 'TestTable'.
at org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.doTranslate(SQLErrorCodeSQLExceptionTranslator.java:231)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:73)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:416)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:440)
at com.xxxx.xxxx.xxxx.service.database.StageService.lambda$updateProcessFlag$18(StageService.java:280)
at java.util.HashMap$KeySet.forEach(HashMap.java:928)
and the "TestTable" is not a table which I want to use.
To solve this problem I remove the test case which modify testService.

How to create an instance of HttpServletRequest for unit testing?

While doing some searches on SO I came across this piece of code to extract the "appUrl" from a URL:
public static String getAppUrl(HttpServletRequest request)
{
String requestURL = request.getRequestURL().toString();
String servletPath = request.getServletPath();
return requestURL.substring(0, requestURL.indexOf(servletPath));
}
My question is how does one unit test something like this? The key problem is how to create an instance of HttpServletRequest for unit testing?
Fwiw I tried some googling and most of the responses center around mocking the class. But if I mock the class so that getRequestURL returns what I want it to return (taking an example since mocking essentially overrides some methods to return canned values), then I am not really testing the code at that point. I also tried the httpunit library but that also does not help.
I use mockito and here is the block of code in the test method I use to mock it up:
public class TestLogin {
#Test
public void testGetMethod() throws IOException {
// Mock up HttpSession and insert it into mocked up HttpServletRequest
HttpSession session = mock(HttpSession.class);
given(session.getId()).willReturn("sessionid");
// Mock up HttpServletRequest
HttpServletRequest request = mock(HttpServletRequest.class);
given(request.getSession()).willReturn(session);
given(request.getSession(true)).willReturn(session);
HashMap<String,String[]> params = new HashMap<>();
given(request.getParameterMap()).willReturn(params);
// Mock up HttpServletResponse
HttpServletResponse response = mock(HttpServletResponse.class);
PrintWriter writer = mock(PrintWriter.class);
given(response.getWriter()).willReturn(writer);
.....
Hope that helps, I use this to test methods that require servlet objects to work.

JMS Testing - JMSTemplate send not executed

I have code piece sending jms messages via Spring JMSTemplate. For testing the the method i use Mockito.
My code looks like following.... publishDialogueServiceMessage()->
brokerUrl = jmsQueueProperties.getProperty(MessageRouterConstants.JMS_QUEUE_URL);
LOG.info("The broker url is : {}", brokerUrl);
jmsTemplate.send(jmsQueueProperties.getProperty(MessageRouterConstants.QUEUE), new MessageCreator() {
#Override
public Message createMessage(Session session) throws JMSException {
ObjectMessage obj = session.createObjectMessage(serviceResponse);
messageSent = true;
return obj;
}
});
In above code to i set boolean variable true, to check that if the message is sent
My Test looks following,
#Before
public void setUp() throws Exception {
connectionFactory = Mockito.spy(new ActiveMQConnectionFactory(
"vm://localhost?broker.persistent=false"));
conn = connectionFactory.createConnection();
conn.start();
}
#After
public void cleanUp() throws Exception{
conn.stop();
}
#Test
public void testPublishDialogueServiceMessage()
{
ServiceResponse response = Mockito.mock(
ServiceResponse.class, Mockito.withSettings()
.serializable());
JmsTemplate mockTemplate = Mockito.mock(JmsTemplate.class);
java.util.Properties p = Mockito.mock(java.util.Properties.class);
Mockito.when(p.getProperty(MessageRouterConstants.QUEUE))
.thenReturn("outbound.request.queue");
mockTemplate.setConnectionFactory(connectionFactory);
mockTemplate.setDeliveryPersistent(true);
mockTemplate.setSessionAcknowledgeMode(2);
mockTemplate.setSessionTransacted(true);
ReflectionTestUtils.setField(publisher, "jmsQueueProperties", p);
ReflectionTestUtils.setField(publisher, "jmsTemplate", mockTemplate);
// test
publisher.publishDialogueServiceMessage(response);
ArgumentCaptor<MessageCreator> msgCreator = ArgumentCaptor.forClass(MessageCreator.class);
Mockito.verify(p, Mockito.times(2))
.getProperty(Mockito.anyString());
Mockito.verify(mockTemplate, Mockito.times(1)).send(
Mockito.anyString(), Mockito.any(MessageCreator.class));
//MessageCreator msgCrt = Mockito.spy(msgCreator.getValue());
//Assert.notNull(msgCrt);
Assert.isTrue(publisher.isMessageSent());
}
In test i facing an interesting problem as publisher.isMessageSent() always returns me FALSE indicating that send message seems not executed(?). but Mockito.verify(mockTemplate, Mockito.times(1)).send(Mockito.anyString(), Mockito.any(MessageCreator.class)); goes fine.
I am wondering what is the cause that my messageSent variable not setting. Can anyone shed some light what I might be doing wrong.
Simple, you have a mock for the jmsTemplate (your mockTemplate). When a method is invoked on a mock it doesn't do anything other than record the call to the mock. So the mock doesn't know that it should attempt to invoke the msgCreator.
Looking at your test I see some obvious issues that suggest a lack of knowledge of Mockito. Why are you setting all of those fields on mockTemplate? It is a mock, it will not use those fields anyway. This also suggests that you don't need the code in your #Before and #After.
If you REALLY want your test to send a message via JMS (and thereby invoke the message createor) you should use a spy on JmsTemplate instead of a mock. However, I would highly discourage this as your test will be dependent on an external system and you would in effect be testing JsmTemplate. The fact that your mock gets invoked properly is sufficient. The only additional thing I think you need to do is to invoke the message creator being passed to the mock to verify that it creates the message correctly.

Run Jettys ServletTester within JUnit test

I'm trying to run Jettys ServletTester in my JUnit test. I created a simple HelloServlet first to test the setup, but I get an IllegalAccessException when I try to request the servlet. Here is what I have so far:
My unit test
#Before
public void setUp() throws Exception {
tester = new ServletTester();
tester.setContextPath("/context");
tester.addServlet(HelloServlet.class, "/hello/*");
tester.start();
}
#After
public void tearDown() throws Exception {
tester.stop();
}
#Test
public void testDefaultServlet() throws Exception {
HttpTester request = new HttpTester();
request.setMethod("GET");
request.setHeader("Host","127.0.0.1");
request.setURI("/context/hello/info");
request.setVersion("HTTP/1.0");
HttpTester response = new HttpTester();
response.parse(tester.getResponses(request.generate()));
assertNull(response.getMethod());
assertEquals(200,response.getStatus());
assertEquals("<h1>Hello Servlet</h1>",response.getContent());
}
My HelloServlet
This servlet is defined in the same file as the unit test, because I want it to be there for the initial setup of jetty. After everything is running, I'll remove it (or maybe keep it, but it will stay within the unit test then).
Update This servlet was defined inside the unit test itself because it was meant only as a configuration test for the jetty server itself. But jetty wasn't able to access it, and after moving it into a public class and a file for itself everything worked like expected. See the comment.
class HelloServlet extends HttpServlet {
#Override
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
PrintWriter out = resp.getWriter();
out.println("Hello, World!");
out.flush();
}
}
My Exception...
2009-10-20 09:36:28.973::INFO: Logging to STDERR via org.mortbay.log.StdErrLog
2009-10-20 09:36:28.989::INFO: jetty-6.1.21
2009-10-20 09:36:29.098::INFO: Started LocalConnector#0.0.0.0:1
2009-10-20 09:36:29.161:/context:WARN: unavailable
java.lang.IllegalAccessException: Class org.mortbay.jetty.servlet.Holder can not access a member of class my.package.HelloServlet with modifiers ""
at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:65)
at java.lang.Class.newInstance0(Class.java:349)
at java.lang.Class.newInstance(Class.java:308)
at org.mortbay.jetty.servlet.Holder.newInstance(Holder.java:153)
at org.mortbay.jetty.servlet.ServletHolder.initServlet(ServletHolder.java:428)
at org.mortbay.jetty.servlet.ServletHolder.getServlet(ServletHolder.java:339)
at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:487)
at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:390)
at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182)
at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
at org.mortbay.jetty.Server.handle(Server.java:326)
at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:536)
at org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:915)
at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:539)
at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:212)
at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:405)
at org.mortbay.jetty.LocalConnector.accept(LocalConnector.java:186)
at org.mortbay.jetty.AbstractConnector$Acceptor.run(AbstractConnector.java:707)
at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:582)
Strange enough, because I got this example almost straight from http://docs.codehaus.org/display/JETTY/ServletTester. Any thoughts or maybe a working example of a embedded jetty servlet container in a junit test?
Your HelloServlet must be implemented as a public class:
public class HelloServlet extends HttpServlet { ... }