The read() method is declared abstract in InputStream class. But we are able to read from keyboard using System.in.read().
My question is that 'in' is a reference of InputStream class. So to use read() method in has to refer to some subclass of InputStream.
To what class does 'in' refer to by default? Can we write a code to find answer to this question?
To answer your specific question: Yes, you can find out the class of System.in by writing code.
This is the application you are looking for:
public class SystemDotInClassFinder {
public static void main(String[] args) {
System.out.println(System.in.getClass().getName());
}
}
Running this script produces:
java.io.BufferedInputStream
As you can see in the source code it is a BufferedInputStream:
private static void initializeSystemClass() {
props = new Properties();
initProperties(props);
VM.saveAndRemoveProperties(props);
lineSeparator = props.getProperty("line.separator");
Version.init();
FileInputStream arg = new FileInputStream(FileDescriptor.in);
FileOutputStream arg0 = new FileOutputStream(FileDescriptor.out);
FileOutputStream arg1 = new FileOutputStream(FileDescriptor.err);
setIn0(new BufferedInputStream(arg));
setOut0(newPrintStream(arg0, props.getProperty("sun.stdout.encoding")));
setErr0(newPrintStream(arg1, props.getProperty("sun.stderr.encoding")));
loadLibrary("zip");
Terminator.setup();
VM.initializeOSEnvironment();
Thread arg2 = Thread.currentThread();
arg2.getThreadGroup().add(arg2);
setJavaLangAccess();
VM.booted();
}
Related
I have worked with junit test integration tests and controller tests in spring and usually we test the output of a method but when i tried to test a simple hello world in main method i had no idea how to go about it so will like to get any idea on what do write
public class App
{
public static void main( String[] args )
{
System.out.println( "Hello World!" );
}
}
This is the simple java class any idea how i can test it
I tried to write something like this
public void mainMethodTest() throws Exception{
System.out.println("hello world");
String[] args = null;
Assert.assertEquals(System.out.println("hello world"),App.main(args));
}
You could assign to the System.out variable a ByteArrayOutputStream object which you store the reference in a variable.
Then invoke your main() method and assert that the String content of the ByteArrayOutputStream object contains the expected String:
#Test
public void main() throws Exception{
PrintStream originalOut = System.out; // to have a way to undo the binding with your `ByteArrayOutputStream`
ByteArrayOutputStream bos = new ByteArrayOutputStream();
System.setOut(new PrintStream(bos));
// action
App.main(null);
// assertion
Assert.assertEquals("hello world", bos.toString());
// undo the binding in System
System.setOut(originalOut);
}
Why does it work ?
bos.toString() returns the "Hello World!" String passed in the method under test:
System.out.println( "Hello World!" );
as after setting System.out in this way : System.setOut(new PrintStream(bos));, the out variable refers to a PrintStream object that decorates the ByteArrayOutputStream object referenced by the bos variable.
So any System.out invocations will write bytes in the ByteArrayOutputStream object.
You can change your class this way
import java.io.PrintStream;
public class TestHelloWorld {
public final static void main(String[] args) {
doPrint(System.out);
}
static void doPrint(PrintStream ps) {
ps.println("Hello World");
}
}
and test the doPrint function by providing your own PrintStream you create around a ByteArrayOutputStream:
public void mainMethodTest() throws Exception{
ByteArrayOutputStream data = new ByteArrayOutputStream();
PrintStream ps = new PrintStream(data, true, "UTF-8");
TestHelloWorld.doPrint(ps);
ps.flush();
Assert.assertEquals("Hello World") + System.getProperty("line.separator"), new String(data, "UTF-8"));
}
Another solution is to replace the system's PrintStream by your own:
System.setOut(new PrintStream(data, true, "UTF-8"));
but that's quite ugly and I try to avoid that. Above solution is more clear, easier to maintenance and you can be sure that no other part of a larger application is printing something to STDOUT while you do your test, leading to a failure of it.
You can run Junit from a main method if thats what you mean.
public static void main( String[] args )
{
JUnitCore junit = new JUnitCore();
Result result = null;
try {
result = junit.run(MyTestClass.class);
}
catch(Exception e)
{
e.printStackTrace();
}
int passed = result.getRunCount()-result.getFailureCount();
}
public class MyTestClass{
#Test
public void testAllBrowsers(){
//test code and asserts
}
}
Is it not possible to append to an ObjectOutputStream?
I am trying to append to a list of objects. Following snippet is a function that is called whenever a job is finished.
FileOutputStream fos = new FileOutputStream
(preferences.getAppDataLocation() + "history" , true);
ObjectOutputStream out = new ObjectOutputStream(fos);
out.writeObject( new Stuff(stuff) );
out.close();
But when I try to read it I only get the first in the file.
Then I get java.io.StreamCorruptedException.
To read I am using
FileInputStream fis = new FileInputStream
( preferences.getAppDataLocation() + "history");
ObjectInputStream in = new ObjectInputStream(fis);
try{
while(true)
history.add((Stuff) in.readObject());
}catch( Exception e ) {
System.out.println( e.toString() );
}
I do not know how many objects will be present so I am reading while there are no exceptions. From what Google says this is not possible. I was wondering if anyone knows a way?
Here's the trick: subclass ObjectOutputStream and override the writeStreamHeader method:
public class AppendingObjectOutputStream extends ObjectOutputStream {
public AppendingObjectOutputStream(OutputStream out) throws IOException {
super(out);
}
#Override
protected void writeStreamHeader() throws IOException {
// do not write a header, but reset:
// this line added after another question
// showed a problem with the original
reset();
}
}
To use it, just check whether the history file exists or not and instantiate either this appendable stream (in case the file exists = we append = we don't want a header) or the original stream (in case the file does not exist = we need a header).
Edit
I wasn't happy with the first naming of the class. This one's better: it describes the 'what it's for' rather then the 'how it's done'
Edit
Changed the name once more, to clarify, that this stream is only for appending to an existing file. It can't be used to create a new file with object data.
Edit
Added a call to reset() after this question showed that the original version that just overrode writeStreamHeader to be a no-op could under some conditions create a stream that couldn't be read.
As the API says, the ObjectOutputStream constructor writes the serialization stream header to the underlying stream. And this header is expected to be only once, in the beginning of the file. So calling
new ObjectOutputStream(fos);
multiple times on the FileOutputStream that refers to the same file will write the header multiple times and corrupt the file.
Because of the precise format of the serialized file, appending will indeed corrupt it. You have to write all objects to the file as part of the same stream, or else it will crash when it reads the stream metadata when it's expecting an object.
You could read the Serialization Specification for more details, or (easier) read this thread where Roedy Green says basically what I just said.
The easiest way to avoid this problem is to keep the OutputStream open when you write the data, instead of closing it after each object. Calling reset() might be advisable to avoid a memory leak.
The alternative would be to read the file as a series of consecutive ObjectInputStreams as well. But this requires you to keep count how many bytes you read (this can be implementd with a FilterInputStream), then close the InputStream, open it again, skip that many bytes and only then wrap it in an ObjectInputStream().
I have extended the accepted solution to create a class that can be used for both appending and creating new file.
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
public class AppendableObjectOutputStream extends ObjectOutputStream {
private boolean append;
private boolean initialized;
private DataOutputStream dout;
protected AppendableObjectOutputStream(boolean append) throws IOException, SecurityException {
super();
this.append = append;
this.initialized = true;
}
public AppendableObjectOutputStream(OutputStream out, boolean append) throws IOException {
super(out);
this.append = append;
this.initialized = true;
this.dout = new DataOutputStream(out);
this.writeStreamHeader();
}
#Override
protected void writeStreamHeader() throws IOException {
if (!this.initialized || this.append) return;
if (dout != null) {
dout.writeShort(STREAM_MAGIC);
dout.writeShort(STREAM_VERSION);
}
}
}
This class can be used as a direct extended replacement for ObjectOutputStream.
We can use the class as follows:
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class ObjectWriter {
public static void main(String[] args) {
File file = new File("file.dat");
boolean append = file.exists(); // if file exists then append, otherwise create new
try (
FileOutputStream fout = new FileOutputStream(file, append);
AppendableObjectOutputStream oout = new AppendableObjectOutputStream(fout, append);
) {
oout.writeObject(...); // replace "..." with serializable object to be written
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
How about before each time you append an object, read and copying all the current data in the file and then overwrite all together to file.
easy question is there an other function i can use instead of println, because i want to output a non-static variable to a file usig out.println();
This is my code:
import java.io.*;
public class main {
String outputString ="Math.sqrt(25);" ;
static String outputPath ="src/output.txt";
/**
* #param args
*/
public static void main(String[] args) throws IOException {
File f;
f= new File (outputPath);
//file creation
if(!f.exists()){
f.createNewFile();
System.out.println("File has been created");
}else{
f.delete();
System.out.println("1. File has been deleted");
f.createNewFile();
System.out.println("2. File has been created");
}
//adding string(text) to file
try{
FileWriter outFile = new FileWriter(args[0]);
PrintWriter out = new PrintWriter(outFile);
out.println(outputString);
out.close();
}catch(IOException e){
e.printStackTrace();
}
}
}
if that is not posible maybe there is an whole other way to go around it. my main problem is that i want to make a string in to peace of code. But that seem to be hard to do :) any help on that :)
The problem has nothing to do with println(). It has to do with the fact that, being non-static, outputString is associated with an instance of your class, and your code creates no such instance.
Either make outputString static, or create an instance of main:
public void doit(String[] args) throws IOException {
...
PrintWriter out = ...;
out.println(outputString);
...
}
public static void main(String[] args) throws IOException {
new main().doit(args);
}
The println function can print both static and non-static variables. The problem is that you're trying to access a non-static variable outputString from within a static context (your main method).
println is a non-static method of the PrintStream class. System, also a class, has a static member called out of type PrintStream which you can retrieve via the System.out call. This member is initialized when java is started.
Note that this does not in any way imply that this is anything other than a regular Object of type PrintStream, it's just that it's a singleton that is conveniently accessible statically from System.
I have class that gets GenericFile as input argument reads data and does some additional processing. I need to test it:
public class RealCardParser {
public static final Logger l = LoggerFactory.getLogger(RealCardParser.class);
#Handler
public ArrayList<String> handle(GenericFile genericFile) throws IOException {
ArrayList<String> strings = new ArrayList<String>();
FileInputStream fstream = new FileInputStream((File) genericFile.getFile());
DataInputStream in = new DataInputStream(fstream);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String strLine = br.readLine();//skip header
while ((strLine = br.readLine()) != null) {
l.info("handling in parser: {}", strLine);
strings.add(strLine);
}
br.close();
return strings;
}
}
The issue is with new FileInputStream. I can mock GenericFile but it is useless cause FileInputStream checks if file exists. I changed my class so:
public class RealCardParser {
public static final Logger l = LoggerFactory.getLogger(RealCardParser.class);
protected BufferedReader getBufferedReader(GenericFile genericFile) throws FileNotFoundException {
FileInputStream fstream = new FileInputStream((File) genericFile.getFile());
DataInputStream in = new DataInputStream(fstream);
return new BufferedReader(new InputStreamReader(in));
}
#Handler
public ArrayList<String> handle(GenericFile genericFile) throws IOException {
ArrayList<String> strings = new ArrayList<String>();
BufferedReader br = getBufferedReader(genericFile);
String strLine = br.readLine();//skip header
while ((strLine = br.readLine()) != null) {
l.info("handling in parser: {}", strLine);
strings.add(strLine);
}
br.close();
return strings;
}
}
So now I can override method getBufferedReader and test method handler:
#RunWith(MockitoJUnitRunner.class)
public class RealCardParserTest {
RealCardParser parser;
#Mock
GenericFile genericFile;
#Mock
BufferedReader bufferedReader;
#Mock
File file;
#Before
public void setUp() throws Exception {
parser = new RealCardParser() {
#Override
public BufferedReader getBufferedReader(GenericFile genericFile) throws FileNotFoundException {
return bufferedReader;
}
};
when(genericFile.getFile()).thenReturn(file);
when(bufferedReader.readLine()).thenReturn("header").thenReturn("1,2,3").thenReturn(null);
}
#Test
public void testParser() throws Exception {
parser.handle(genericFile);
//do some asserts
}
}
Handler method now is covered with tests, but I still have uncovered method getBufferedReader that leads to cobertura problems.
How to test method getBufferedReader or maybe there is another solution of the problem?
You can mock FileInputStream by using PowerMockRunner and PowerMockito. See the below code for mocking-
#RunWith(PowerMockRunner.class)
#PrepareForTest({
FileInputStream.class
})
public class A{
#Test
public void testFileInputStream ()
throws Exception
{
final FileInputStream fileInputStreamMock = PowerMockito.mock(FileInputStream.class);
PowerMockito.whenNew(FileInputStream.class).withArguments(Matchers.anyString())
.thenReturn(fileInputStreamMock);
//Call the actual method containing the new constructor of FileInputStream
}
}
Maybe this is a bad idea, but my first approach would have been creating an actual test-file rather than mocking the stream object.
One could argue that this would test the GenericFile class rather than the getBufferedReader method.
Maybe an acceptable way would be to return an actually existing test-file through the mocked GenericFile for testing the getBufferedReader?
I would first extract the creation of the Stream into a dependency. So your RealCardParser gets a StreamSource as a dependency.
Now you can take appart your problem:
for your current test provide a mock (or in this case I would prefer a fake) implementation returning a Stream constructed from a String.
Test the actual StreamSource with a real file, ensuring that it returns the correct content and what not.
I know this isn't the answer that you want.
The idea of unit testing is to make sure your logic is correct. Unit tests catch bugs where incorrect logic has been written. If a method contains no logic (that is, no branching, looping or exception handling), then it is uneconomical to unit test it. By that, I mean that a unit test costs money - time to write it, and time to maintain it. Most unit tests pay us back for that investment, either by finding bugs, or re-assuring us that there are no bugs in the domain of what is being tested.
But a unit test for your getBufferedReader method would not pay you back for our investment. It has a finite cost, but zero benefit, because there is no actual logic that can go wrong. Therefore, you should NOT write such a unit test. If your Cobertura settings or your organisational standards require the existence of such a unit test, then those settings or standards are WRONG and should be changed. Otherwise, your employer's money is being spent on something that has an infinite cost:benefit ratio.
I strongly recommend that your standards are changed so that you only write unit test for methods that contain branching, looping or exception handling.
When you are having this question. You are probably not following dependency inversion principle correctly. You should use InputStream whenever it's possible. If your write your FileInputStream adapter method like this:
class FileReader {
public InputStream readAsStream() {
return new FileInputStream("path/to/File.txt");
}
}
Then you can mock the method to return ByteArrayInputStream alternatively. This is much easier to deal with, because you only need to pass a string to the stream instead of dealing with the specific FileInputStream implementation.
If you are using mockito to mock, the sample goes like this:
FileReader fd = mock(FileReader());
String fileContent = ...;
ByteArrayInputStream bais = new ByteArrayInputStream(fileContent);
when(fd.readAsStream()).thenReturn(bais);
how can I write a JUnit test, that checks if a FileInputStream has been closed?
Consider the following code,
import java.io.FileInputStream;
class FileInputStreamDemo {
public static void main(String args[]) throws Exception {
FileInputStream fis = new FileInputStream(args[0]);
// Read and display data
int i;
while ((i = fis.read()) != -1) {
System.out.println(i);
}
fis.close();
}
}
I would like to write a test like this:
#Test
public void test() {
FileInputStreamDemo.main("file.txt");
// test here, if input stream to file is closed correctly
}
Although this code example doesn't make much sense, I would like to now how to write a JUnit test that checks if the FIS has been closed. (If possible: without even having a reference to the original FIS object)
You should create a separate class called MyFileReader which does the job of reading the file. You then create a class MyFileReaderTest which instantiates your new class and calls the methods in it to test that it behaves correctly. If you make fis a protected member of the MyFileReader class the test can access fis and verify it has been closed.
Instead of using FileInputStream you should use an interface like InputStream so that you can create a MockInputStream which doesn't really create a file but keeps track of whether close() was called on it. Then you can test for that in your test code.