Lab#SE02-5: Movie/Review, simulate interactivity by console
Java SE Lab 02
📘 Linux Lab#LI02-5: interactivity and console
Once in previous Lab#SE02-4, the user enjoys some interactivity with our app, let’s test this new feature.
To do so, with the class
Movie
in mind, we could create acreateFromConsole()
method, a method that eventually:- prompts the user for input in the console
- creates a Movie object based on that input
- uses the Scanner class to read the input from the console
- sets the fields of the Movie object with the input data.
And then, test this method
createFromConsole()
with a JUnit @Test:- a test that simulates a user input by setting the input stream to a string containing the input data,
- and then creating a
Movie
object and calling thecreateFromConsole()
method.
The lazy programmer will reuse whatever they can to get their work done. This virtue leads to code reuse by encouraging code to be written only once - Larry Wall, The three virtues of a programmer
1 Overview
Package java.io, provides for system input and output through data streams, serialization and the file system.
Programming simple I/O operations is easy, which involves only a few classes and methods. You could do it by looking at a few samples like our previous lab.
Programming efficient, portable I/O is extremely difficult, especially if you have to deal with different character sets.
1.1 Stream
A stream
is a sequence of data. In Java, a stream is composed of bytes
. It’s called a stream because it is like a stream of water that continues to flow.
In our app, java.io
will create three streams automatically. All these streams are attached with the console.
System.out
: standard output streamSystem.in
: standard input streamSystem.err
: standard error stream
Input stream
refers to an ordered flow of data in the form of bytes. This flow of data can be coming from various resources such as files, network programs, input devices, etc.
In order to read such data, we have a Java InputStream Class
in the Java IO API
. Link
1.2 Discuss solution
These lines of pseudo-code
, particulary the (2) line, are the key-solution to use InputStream to simulate a input console.
(1) String simulateInputByConsole = "Here\ngoes\nhe\nsimulate\nimput";
(2) InputStream in <<<<< simulateInputByConsole.getBytes();
(3) System.setIn(in);
It creates an InputStream
in
that reads from a byte array
containing the bytes of the input string input.getBytes()
(using the platform’s default charset), which allow us to use this InputStream
as regular input stream into System.in.
A new InputStream
object is being created by wrapping a ByteArrayInputStream
around a byte array.
String input = "The Shawshank Redemption\n" +
InputStream in = new ByteArrayInputStream(input.getBytes());
A ByteArrayInputStream
is a subclass of InputStream
that reads data from a byte array
.
The byte array is created by calling the getBytes()
method on the input string. getBytes()
is a method of the String
class that returns a byte array
containing the characters of the string encoded using the platform’s default charset.
1.3 getBytes()
String myString = "I love Java";
byte[] byteArray;
// convert the string to a byte array
// using platform's default charset
byteArray = myString.getBytes();
System.out.println(Arrays.toString(byteArray));
// Output
// [73, 32, 108, 111, 118, 101, 32, 74, 97, 118, 97]
We have used the Arrays
class in the above example to print the byte array in a readable form. It has nothing to do with getBytes()
.
HTML Encoding Character Set
more examples
There are many other standard charset like:
US-ASCII
: Seven-bit ASCII, a.k.a. ISO646-US, a.k.a. the Basic Latin block of the Unicode character setISO-8859-1
: ISO Latin Alphabet No. 1, a.k.a. ISO-LATIN-1UTF-8
: Eight-bit UCS Transformation FormatUTF-16BE
: Sixteen-bit UCS Transformation Format, big-endian byte orderUTF-16LE
: Sixteen-bit UCS Transformation Format, little-endian byte orderUTF-16
: Sixteen-bit UCS Transformation Format, byte order identified by an optional byte-order mark.
1.4 ByteArrayInputStream
// Creates a ByteArrayInputStream that reads entire array
ByteArrayInputStream input = new ByteArrayInputStream(byte[] arr);
The ByteArrayInputStream
class of the java.io
package ìs used to read an array of input data (in bytes).
2 Core classes
2.1 createFromConsole()
The method createFromConsole()
is used to prompt the user for input in the console and create a movie object based on that input.
It uses the Scanner
class to read the input from the console and sets the fields of the Movie
object with the input data
.
You could then use these:
Movie.java
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Movie {
private String title;
private int year;
private String director;
private String actors;
public void createFromConsole() {
Scanner scanner = new Scanner(System.in);
System.out.print("Enter the title of the movie: ");
title = scanner.nextLine();
System.out.print("Enter the year the movie was released: ");
year = scanner.nextInt();
scanner.nextLine(); // consume the newline character
System.out.print("Enter the name of the director: ");
director = scanner.nextLine();
System.out.print("Enter the names of the actors" +
" (separated by commas): ");
actors = scanner.nextLine();
}
// getters adn setters by lombok
}
2.2 testCreateMovieFromConsoleInput()
The method testCreateMovieFromConsoleInput()
is a JUnit
test that is used to test the createFromConsole()
method.
This test simulates user input
by setting the input stream to a string containing the input data, and then creating a Movie
object and calling the createFromConsole()
method.
Then it uses the assertEquals
method to check that the fields of the movie object are set to the correct values, based on the input provided.
MovieTest.java
import org.junit.jupiter.api.Test;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
public class MovieTest {
@Test
public void testCreateMovieFromConsoleInput() {
// Set up input for the console
String input = "The Shawshank Redemption\n" +
"1994\n" +
"Frank Darabont\n" +
"Tim Robbins, Morgan Freeman\n";
InputStream in = new ByteArrayInputStream(input.getBytes());
System.setIn(in);
// Create the movie object
Movie movie = new Movie();
movie.createFromConsole();
// Assert that the movie object was created with the correct data
assertEquals("The Shawshank Redemption", movie.getTitle());
assertEquals(1994, movie.getYear());
assertEquals("Frank Darabont", movie.getDirector());
assertEquals("Tim Robbins, Morgan Freeman", movie.getActors());
}
}
It is important to test the createFromConsole()
method because it is a core functionality of the Movie
class, and it is essential to ensure that it is working properly.
If this method is not working as expected, it will not only affect the user experience but also could cause the application to fail.
This static
method System.setIn()
from the class java.lang.System
is used to reassign the standard input stream
.
Signature: