I have some methods which are private in the class example and I want to use them in the test class for testing purposes, how can I access these methods and leave them as private
import java.util.*;
public class Example
{
Scanner scanner;
public Example()
{
scanner = new Scanner(System.in);
}
private void enterName()
{
System.out.println("Enter name");
String name = scanner.nextLine();
System.out.println("Your name is: " + name);
}
private void enterAge()
{
System.out.println("Enter age");
int age = scanner.nextInt();
System.out.println("Your age is : " + age);
}
public void userInput()
{
enterAge();
enterName();
}
}
public class Test
{
public static void main(String args[])
{
Example n = new Example();
n.enterName();
n.enterAge();
}
}
Why would you test the private methods while one will only use the public one? Unit testing is about testing for expected behavior. Public methods expose that behavior.
If you want to test the output generated you could implement a protected method to write to out e.g.
public class Example {
// code omitted
private void enterName() {
writeMessage("Enter name");
String name = scanner.nextLine();
writeMessage("Your name is: " + name);
}
protected void writeMessage(String msg) {
System.out.println(msg);
}
}
In your test you could then create a private class which extends Example and overrides the writeMessage method.
public class ExampleTest {
public testOutput() {
MyExample e = new MyExample();
e.userInput();
String output = e.getOutput();
// test output string
}
private class MyExample extends Example {
private String output = "";
public String getOutput() {
return output;
}
#Override
public void writeMessage(String msg) {
output += msg;
}
}
}
You also might want a setter or constructor which can inject the Scanner object. This will make testing easier since you could then inject a mocked scanner version.
Unit-testing is indeed black-box testing, so you cannot, and should not, access the private (inner mechanisms) methods. However, white-box testing is often called assertion-based verification. Just put assertions (or it-then-throw statements) everywhere, and your black-box unit test will become a white-box test.
More specifically, try to put pre-conditions and post-conditions as much as possible in your private methods to verify the inputs and the outputs. Therefore, you define a contract between every method caller and callee. If something goes wrong, you'll quickly see where and why.
See Design-by-Contract for more info!
Related
I want to create the below class
associatename:String
workstatus:String
associate() :constructor
getassociatename():String
setassociatename(String):void
getworkstatus()String
tracksassociatestatus():int
setworkstatus(String):void
The trackAssociateStatus method takes the number of days as argument and sets the work status of the associate based on the number of days. The first 20 days they learn “C”, the next 20 days they learn “Java” In the Main class invoke the trackAssociateStatus method and find the work status and display the output.
output:The associate abc work status:Project phase
I tried this....But i got error
//associate class
public class associate{
private int associatename;
private String workstatus;
private int days;
void associate()
{
getassociatename();
setassociatename();
getworkstatus();
tracksassociatestatus();
setworkstatus();
}
public int getassociatename()
{
return associatename;
}
public void setassociatename(int associatename)
{
this.associatename=associatename;
}
public String getworkstatus()
{
return workstatus;
}
public void tracksassociatestatus(int days)
{
if(days<20)
setworkstatus("C");
else
setworkstatus("Java");
}
public void setworkstatus(String workstatus)
{
this.workstatus=workstatus;
}
}
//main class
associate a =new associate();
Scanner in=new Scanner(System.in);
int associateid=0;
String workstatus=null;
int days=0;
System.out.println("Enter the associateid:");
associateid=in.nextInt();
a.associateid=(associateid);
System.out.println("Enter the no of days:");
days=in.nextInt();
a.trackassociatestatus();
System.out.println("The id is "+a.getassocaiteid()+" work status "+a.getworkstatus());
Based on your (seemingly) UML spec, your class would look like the following:
public class Associate {
private String associateName;
private String workStatus;
public Associate() {
// This constructor is optional, a no-args constructor is added by the compiler to any class not explicitly naming a constructor.
}
public String getAssociateName() {
return associateName;
}
public void setAssociateName(String associateName) {
this.associateName = associateName;
}
public String getWorkStatus() {
return workStatus;
}
public void setWorkStatus(String workStatus) {
this.workStatus = workStatus;
}
public int tracksAssociateStatus() {
// TODO write logic here
return 1; // TODO change to whatever you need to return
}
}
You were specifying int for getAssociateName, when associateName is a String. This won't work; you need your getter return type to be the same as your field data type, or you need to convert the data to the method's return type. (The former is best practice).
Constructors don't specify a type, the class name is used and the compiler will understand what you want to do (which is return a new instance of the class). Therefore, your void associate() will tell the compiler "create a method called associate that doesn't return anything".
Well, would be nice if you provide the error itself for us.
But meanwhile, have you notice that your tracksassociatestatus method recieves an integer parameter days, and your constructor passes nothing to it?
So try changing your constructor to be something like:
Public associate() {
getassociatename();
setassociatename();
getworkstatus();
tracksassociatestatus(10);
setworkstatus();
}
For a cleaner code, check the other answer.
If you still have errors, please share them.
import java.util.*;
public class Associate
{
private String associateName;
private int workStatus;
private int days;
Scanner sc = new Scanner(System.in);
public String getAssociateName()
{
System.out.println("Enter the Associate id:");
associateName = sc.nextLine();
return associateName;
}
public void setassociatename(int associatename)
{
this.associateName=associateName;
}
public String tracksAssociatename()
{
return associateName;
}
public int getWorkStatus()
{
System.out.println("Enter the number of days");
days = sc.nextInt();
return days;
}
public void setWorkStatus(String workStatus)
{
this.workStatus=workStatus;
}
enter code here
public `enter code here`int tracksAssociateStatus()
{
return days;
}
public static void main(String args[])
{
Associate obj = new Associate();
obj.getAssociateName();
obj.getworkstatus();
System.out.println("The Associate name "+obj.tracksAssociatename()+" work Status "+obj.tracksAssociateStatus());
}
}
Task: have a class that implements something in different ways. User of class should only see public enum that represents available options, while hiding all implementation of different behavior.
To avoid checking the provided "style" on every call of method, constructor uses switch on enum value provided to assign appropriate inner private class to a field.
Here is SSCCE:
public class Greeter {
public enum GreetingStyle { HEY, HELLO }
private String name;
private GreetingChooser greetingChooser;
public Greeter(String name, GreetingStyle style) {
this.name = name;
switch(style) {
case HEY:
greetingChooser = new Hey();
break;
case HELLO:
greetingChooser = new Hello();
break;
default :
throw new UnsupportedOperationException("GreetingStyle value not handled : " + style.toString());
}
}
public void greet() {
// need to avoid switch(style) here
System.out.println(greetingChooser.greeting() + ", " + name + "!");
}
// this interface can't be public
private interface GreetingChooser {
String greeting();
}
private class Hey implements GreetingChooser {
public String greeting() {
return "Hey";
}
}
private class Hello implements GreetingChooser {
public String greeting() {
return "Hello";
}
}
public static void main(String args[]) {
new Greeter("John Doe", Greeter.GreetingStyle.HEY).greet();
new Greeter("John Doe", Greeter.GreetingStyle.HELLO).greet();
}
}
Question: is it a good way to implement such a functionality to make it maintainable in the future (e.g. we'll need to add GreetingStyle ALOHA)? Another idea I had was to use a static map
private static final Map<GreetingStyle, GreetingChooser> greetingMap;
static {
greetingMap = new HashMap<>();
greetingMap.put(Greeter.GreetingStyle.HEY, new Hey());
greetingMap.put(Greeter.GreetingStyle.HELLO, new Hello());
}
and to use greetingMap.get(style) in constructor.
Note: in Java 8 it would be probably best implemented with lambdas (if interface only has one function), but I'm constrained to Java 7.
Instead of just using the enum as a constant for the factory switch, you could avoid the switch by equipping the enum constant with either configuration
public enum GreetingStyle
{
HEY("Hey"),
HELLO("Hello");
GreetingStyle(String text) {
this.text = text;
}
public final String text;
}
or behaviour:
public enum GreetingStyle
{
HEY {
public void greet() { /* performs hey style greeting*/ }
},
HELLO{
public void greet() { /* performs hello style greeting*/ }
};
public abstract void greet();
}
Why are you bound to the enum? What you describe can be easily achieved using polymorphism. If you worry about extending it in the future, you can use design patterns such as Factory or Decorator.
I am learning Java and currently attempting to combine if statements and multiple class files.
It is a simple I/O program with a twist, if userName = JDoe I want the program to say something other than the standard saying.
From main.java:
import java.util.Scanner;
import java.lang.String;
class main {
public static void main(String[] args){
Scanner input = new Scanner(System.in);
UInput uInput = new UInput();
System.out.println("What is your name: ");
uInput.setName(input.nextLine());
uInput.saying();
}
}
class ifMain {
public static void main(String[] args){
String userName = "JDoe";
if (test.matches("JDoe")) {
System.out.println("You smell!");
} else {
UInput.saying();
}
}
}
From UInput.java:
public class UInput {
private String userName;
public void setName(String name){
userName = name;
}
public String getName(){
return userName;
}
public void saying(){
System.out.printf("Hello %s", getName());
}
}
However, in class ifMain{}, IntelliJ is saying "Variable userName never used", what am I missing?
See comments:
class ifMain {
public static void main(String[] args){
String userName = "JDoe"; // <=== Declared here
if (test.matches("JDoe")) { // <=== Not used here
System.out.println("You smell!");
} else {
UInput.saying();
}
}
}
The local variable userName is never used in the main method of the ifMain class.
You probably meant:
if (test.matches(userName)) {
Side note: The overwhelming convention in Java is that class names start with an uppercase character. So IfMain, not ifMain.
Your program wouldn't even compile in first place. I believe that you are new to Java. But still, look at this code.
class ifMain {//Please change the class name to CamelCase convention
public static void main(String[] args){
String userName = "JDoe";
if (test.matches("JDoe")) {// Compile error. Variable test is not declared.
System.out.println("You smell!");
} else {
UInput.saying();
}
}
}
Are you trying in a notepad and executing it? You can try using eclipse/NetBeans/IntelliJ IDEs in that case to help you better.
public class QuestionBank {
public static void main(String[] args) {
int k = 0;
String Bank[][] = {{"The sun is hot.","A. True","B. Flase","A"},
{"Cats can fly.","A. True","B. False","B"}};
}
}
Above is my QuestionBank class that creates a 2X4 string array. First column being the question, 2nd and 3rd being the answer choices, and 4th being the correct answer.
Below is my RealDeal class.
import javax.swing.JOptionPane;
import java.util.Scanner;
public class RealDeal {
public static void main(String[] args) {
input = JOptionPane.showInputDialog(Bank[0][0]\nBank[0][1]\nBank[0][2]);
if (input == Bank[0][3]) {
input = 10;
} else {
input = 0;
}
total = input/1;
JOptionPane.showMessageDialog(null,"You scored a " + total + " out of 10. Great job!");
System.exit(0);
}
}
What I'm trying to do is to get Bank[0][0], Bank[0][1], and Bank[0][2] to output on my RealDeal class and then to check whether Bank[0][3] matches with the users input. Can anyone please help me with this. Im really new to java so if anyone could actually draw out the answer and explain it to me that would be great.
I think the best way is reading a good Java book and become familiar with the language itself and then try to solve this by your own. If you then have a real question there is no problem asking it here again. But your code is... not really working at all.
I don't think this portal is a "please do my work for me" portal.
To call anything from another class you will need to either setup a method for a return or make the variables public.
So:
public class Class1
{
// for method 1
public String s1 = "This is a string"
// for method 2
public Class1 {}
public returnString()
{
return s1;
}
}
public class CLASS2
{
public static void main(String args[])
{
// get the class
cls1 = new Class1();
// retrieving - method 1
String str = cls1.s1;
// retrieving - method2
str = cls1.returnString();
}
}
I am a beginner programmer and this is my first question on this forum.
I am writing a simple text adventure game using BlueJ as a compiler, and I am on a Mac. The problem I ran into is that I would like to make my code more self automated, but I cannot call a class with a string. The reason I want call the class and not have it all in an if function is so that I may incorporate more methods.
Here is how it will run currently:
public class textadventure {
public method(String room){
if(room==street){street.enterRoom();}
}
}
public class street{
public enterRoom(){
//do stuff and call other methods
}
}
The if statement tests for every class/room I create. What I would like the code to do is automatically make the string room into a class name that can be called. So it may act like so:
Public method(string room){
Class Room = room;
Room.enterRoom();
}
I have already looked into using Class.forName, but all the examples were too general for me to understand how to use the function. Any help would be greatly appreciated, and if there is any other necessary information (such as more example code) I am happy to provide it.
-Sebastien
Here is the full code:
import java.awt.*;
import javax.swing.*;
public class Player extends JApplet{
public String textOnScreen;
public void start(){
room("street1");
}
public void room(String room){
if(room=="street1"){
textOnScreen=street1.enterRoom();
repaint();
}
if(room=="street2"){
textOnScreen=street2.enterRoom();
repaint();
}
}
public void paint(Graphics g){
g.drawString(textOnScreen,5,15);
}
}
public abstract class street1
{
private static String textToScreen;
public static String enterRoom(){
textToScreen = "You are on a street running from North to South.";
return textToScreen;
}
}
public abstract class street2
{
private static String textToScreen;
public static String enterRoom(){
textToScreen = "You are on another street.";
return textToScreen;
}
}
Seeing as you are rather new to programming, I would recommend starting with some programs that are simpler than a full-fledged adventure game. You still haven't fully grasped some of the fundamentals of the Java syntax. Take, for example, the HelloWorld program:
public class HelloWorld {
public static void main(String[] args) {
String output = "Hello World!"
System.out.println(output);
}
}
Notice that public is lowercased. Public with a capital P is not the same as public.
Also notice that the String class has a capital S.* Again, capitalization matters, so string is not the same as String.
In addition, note that I didn't have to use String string = new String("string"). You can use String string = "string". This syntax runs faster and is easier to read.
When testing for string equality, you need to use String.equals instead of ==. This is because a == b checks for object equality (i.e. a and b occupy the same spot in memory) and stringOne.equals(stringTwo) checks to see if stringOne has the same characters in the same order as stringTwo regardless of where they are in memory.
Now, as for your question, I would recommend using either an Enum or a Map to keep track of which object to use.
For example:
public class Tester {
public enum Location {
ROOM_A("Room A", "You are going into Room A"),
ROOM_B("Room B", "You are going into Room B"),
OUTSIDE("Outside", "You are going outside");
private final String name;
private final String actionText;
private Location(String name, String actionText) {
this.name = name;
this.actionText = actionText;
}
public String getActionText() {
return this.actionText;
}
public String getName() {
return this.name;
}
public static Location findByName(String name) {
name = name.toUpperCase().replaceAll("\\s+", "_");
try {
return Enum.valueOf(Location.class, name);
} catch (IllegalArgumentException e) {
return null;
}
}
}
private Location currentLocation;
public void changeLocation(String locationName) {
Location location = Location.findByName(locationName);
if (location == null) {
System.out.println("Unknown room: " + locationName);
} else if (currentLocation != null && currentLocation.equals(location)) {
System.out.println("Already in room " + location.getName());
} else {
System.out.println(location.getActionText());
currentLocation = location;
}
}
public static void main(String[] args) {
Tester tester = new Tester();
tester.changeLocation("room a");
tester.changeLocation("room b");
tester.changeLocation("room c");
tester.changeLocation("room b");
tester.changeLocation("outside");
}
}
*This is the standard way of formating Java code. Class names are PascalCased while variable names are camelCased.
String className=getClassName();//Get class name from user here
String fnName=getMethodName();//Get function name from user here
Class params[] = {};
Object paramsObj[] = {};
Class thisClass = Class.forName(className);// get the Class
Object inst = thisClass.newInstance();// get an instance
// get the method
Method fn = thisClass.getDeclaredMethod(fnName, params);
// call the method
fn.invoke(inst, paramsObj);
The comments below your question are true - your code is very rough.
Anyway, if you have a method like
public void doSomething(String str) {
if (str.equals("whatever")) {
// do something
}
}
Then call it like
doSomething("whatever");
In Java, many classes have attributes, and you can and will often have multiple instances from the same class.
How would you identify which is which by name?
For example
class Room {
List<Monster> monsters = new ArrayList <Monster> ();
public Room (int monstercount) {
for (int i = 0; i < monstercount; ++i)
monsters.add (new Monster ());
}
// ...
}
Monsters can have attributes, and if one of them is dead, you can identify it more easily if you don't handle everything in Strings.