Java
To evaluate student solutions written in Java, you need to write tests using JUnit.

Basics

Let's start with a basic exercise. Your student is to implement a HelloWorld class with a function helloWorld() that returns the string "Hello World". For the sake of simplicity, it doesn't print anything.
Here is an example solution:
1
public class HelloWorld {
2
public String helloWorld() {
3
return "Hello World";
4
}
5
}
Copied!
And this is an example test of the student's code:
1
import org.junit.Test;
2
import org.junit.Assert;
3
4
public class Evaluate {
5
HelloWorld hw = new HelloWorld();
6
7
@Test
8
public void testHelloWorld() {
9
Assert.assertEquals("It doesn't return 'Hello World'",
10
"Hello World", hw.helloWorld());
11
}
12
}
Copied!
Let's examine the above test code.
Evaluate Class
Your test code must live inside a class named Evaluate . It is, otherwise, just a plain java class.
@Test
This is a JUnit annotation that indicates a test function. You add this annotation before each of your test cases.
assertEquals
This is a method provided by JUnit which compares the expected value and actual value. It takes 3 arguments:
    Feedback message to be shown if values are not equal
    Expected value
    Actual value
You can see other assertions here.
Our test class has a test case testHelloWorld() which asserts equality of "Hello World" and student's function's output.

Testing Outputs

Let's change the previous example a little bit and ask students to print "Hello World" rather than returning the string.
Here is the example solution:
1
public class HelloWorld {
2
public void helloWorld() {
3
System.out.print("Hello World");
4
}
5
}
Copied!
To be able to test the student code, you must be able to read stdout after calling helloWorld() function. For this purpose, we have provided helper class named IOHelper.
For example:
1
import org.junit.Test;
2
import org.junit.Assert;
3
import com.udemy.ucp.IOHelper;
4
5
public class Evaluate {
6
HelloWorld hw = new HelloWorld();
7
IOHelper helper = new IOHelper();
8
9
@Test
10
public void testHelloWorld() {
11
helper.resetStdOut(); // clean stdout
12
hw.helloWorld();
13
Assert.assertEquals("It doesn't print 'Hello World'",
14
"Hello World", helper.getOutput());
15
}
16
}
Copied!
There are a few differences between this test and the previous one:
    We are using IOHelper to gain access to data written to stdout.
    Calling IOHelper.resetStdOut() removes output that's been captured so far.
    Comparing "Hello World" string with output that we read with IOHelper.getOutput().
In this specific case, calling resetStdOut() before getOutput() isn't needed. But, in general, it's a recommended practice. You can see more details about IOHelper below in other examples.

Testing Field and Method Declarations

Now let's change the example and see how to validate if students have declared fields and methods.
Let's consider that the student's task is to declare two fields (name and lastName ) and two methods (printName() and printNumber(int) ) in an Applicant class. For the sake of simplicity, methods can have empty bodies because we don't really care about the behavior here.
The solution for this problem could be implemented as follows:
1
public class Applicant {
2
public String name;
3
public String lastName;
4
5
public void printName() {}
6
public void printNumber(int number) {}
7
}
Copied!
To be able to test this code, you will need to know whether these fields and methods are declared or not. For this purpose, we have provided EvaluationHelper , which is explained below:

Check if a field is declared in a class

1
public boolean isFieldDeclared(Object obj, String fieldName)
Copied!
    obj: Instance of the class
    fieldName: Name of the field to be checked

Check if a method is declared in a class

1
public boolean isMethodDeclared(Object obj, String methodName,
2
Class<?>... parameterTypes)
Copied!
    obj: Instance of the class
    methodName: Name of the method to be checked
    parameterTypes: Types of parameters the method expects such as int.class
Below, you can see an example of how to test the student's code:
1
import org.junit.Test;
2
import org.junit.Assert;
3
import com.udemy.ucp.EvaluationHelper;
4
5
public class Evaluate {
6
EvaluationHelper helper = new EvaluationHelper();
7
Applicant applicant = new Applicant();
8
9
@Test
10
public void testFieldDeclarations() {
11
if (!helper.isFieldDeclared(applicant, "name")) {
12
Assert.fail("'name' field is not declared.");
13
}
14
// You can also check if the field has a specific type
15
// Following line is checking if Applicant class has
16
// a String field named "surname"
17
if (!helper.isFieldDeclared(applicant, "surname", String.class)) {
18
Assert.fail("'surname' field is not declared.");
19
}
20
}
21
22
@Test
23
public void testMethodDeclarations() {
24
if (!helper.isMethodDeclared(applicant, "printName")) {
25
Assert.fail("'printName' method is not declared.");
26
}
27
if (!helper.isMethodDeclared(applicant, "printNumber", int.class)) {
28
Assert.fail("'printNumber' method is not declared.");
29
}
30
}
31
}
Copied!
When these tests fail, they show relevant error messages to students by calling Assert.fail().

Providing Inputs

How do you test whether students are able to read input from stdin?
Consider that the student's task is to read a customer's first and last name from stdin and print the full name to stdout.
The solution for this problem can be implemented as follows:
1
import java.util.Scanner;
2
3
public class Customer {
4
public String firstName;
5
public String lastName;
6
7
public String getFullName() {
8
Scanner scanner = new Scanner(System.in);
9
System.out.println("Enter your first name:");
10
this.firstName = scanner.next();
11
System.out.println("Enter your last name:");
12
this.lastName = scanner.next();
13
return this.firstName + " " + this.lastName;
14
}
15
}
Copied!
IOHelper has a method to fill stdin with given values.
1
public void setStdInput(String... inputs)
Copied!
    inputs: String inputs to be entered to stdin. A line separator will be appended to each input.
The following test class enters first and last name in the console and checks whether student's code can return the full name.
1
import org.junit.Test;
2
import org.junit.Assert;
3
4
public class Evaluate {
5
IOHelper helper = new IOHelper();
6
Customer customer = new Customer();
7
8
@Test
9
public void testGetFullName() {
10
this.helper.setStdInput("Albert", "Einstein");
11
String fullName = this.customer.getFullName();
12
Assert.assertEquals(
13
"For inputs 'Albert' and 'Einstein' it doesn't work.",
14
"Albert Einstein", fullName);
15
}
16
}
Copied!

Testing Declared Values

Consider that the student's task is to implement a class that has two fields (SSN and age ) and a function (setSSN(String)). One other requirement is that the age field's initial value must be 0.
The solution for this problem can be implemented as follows:
1
public class Customer {
2
public String SSN;
3
public int age = 0;
4
5
public void setSSN(String ssn) {
6
this.SSN = ssn;
7
}
8
}
Copied!
The following example tests the values of the declared fields.
1
import org.junit.Test;
2
import org.junit.Assert;
3
4
public class Evaluate {
5
Customer studentSolution = new Customer();
6
7
@Test
8
public void testSetSSN() {
9
// Set customer's Social Security Number
10
this.studentSolution.setSSN("123-45-6789");
11
Assert.assertEquals("'setSSN' did not set customer's SSN properly.",
12
"123-45-6789", this.studentSolution.SSN);
13
}
14
15
@Test
16
public void testInitialAgeValue() {
17
// Check if customer's age is 0 if it's not set
18
Assert.assertEquals("Initial age must be 0.", 0, this.studentSolution.age);
19
}
20
}
Copied!

Testing Exceptions

You can expect student code to raise Exceptions in some cases.
So let's improve the example above and ask students to throw IllegalArgumentException if the input passed to a function is not valid. setSSN() won't accept SSNs shorter than 10 characters and setAge() won't accept negative ages. And if age is negative, the Exception message must be "Age can't be a negative number.".
The solution for this problem can be implemented as follows:
1
public class Customer {
2
private String SSN;
3
private int age = 0;
4
5
public void setSSN(String ssn) {
6
if (ssn.length() < 10) {
7
throw new IllegalArgumentException();
8
}
9
this.SSN = ssn;
10
}
11
12
public void setAge(int age) {
13
if (age < 0) {
14
throw new IllegalArgumentException("Age can't be a negative number.");
15
}
16
this.age = age;
17
}
18
}
Copied!
To check whether the student handled exception cases, you can use JUnit's exception testing. Following test class is checking exceptions.
    **testInvalidSSN** is only checking whether the exception is thrown or not
    **testInvalidAge** is also checking the exception message
1
import org.junit.Rule;
2
import org.junit.Test;
3
import org.junit.Assert;
4
import org.junit.rules.ExpectedException;
5
6
public class Evaluate {
7
@Rule
8
public ExpectedException thrown = ExpectedException.none();
9
Customer studentSolution = new Customer();
10
11
@Test(expected = IllegalArgumentException.class)
12
public void testInvalidSSN() {
13
// Check if it raises exception for invalid Social Security Number
14
this.studentSolution.setSSN("123");
15
}
16
17
@Test
18
public void testInvalidAge() {
19
thrown.expect(IllegalArgumentException.class);
20
thrown.expectMessage("Age can't be a negative number.");
21
// Check if it raises exception for negative age
22
this.studentSolution.setAge(-5);
23
}
24
}
Copied!
You can also use a try / catch block to check whether an exception is thrown and call Assert.fail() if it is not.

Packages and Restrictions

You can ask your students to implement classes inside different packages. However, your test class Evaluate cannot be in a package.
For example, you can ask students to implement a Car class inside com.example.vehicles package.
Here is an example solution:
1
package com.example.vehicles;
2
3
public class Car {
4
5
}
Copied!
And the evaluation of this code can be as follows:
1
import org.junit.Test;
2
import org.junit.Assert;
3
import com.example.vehicles.Car;
4
5
public class Evaluate {
6
@Test
7
public void testPackageNames() {
8
// There's no need to run any tests since importing Car was successful
9
Assert.assertTrue(true);
10
}
11
}
Copied!
The only logical thing the above test code does is that it imports Car class from com.example.vehicles package. If the package wasn't defined, this would raise a compile error. (If you want to avoid the compilation error, you can use the Java reflection API to dynamically lookup and instantiate the student's class).

IOHelper

Let's see all the details of IOHelper class which is provided by Udemy to help you deal with reading outputs of and entering inputs to student solutions.
1
package com.udemy.ucp;
2
3
public class IOHelper {
4
5
/**
6
* Enter values to standard input (stdin).
7
* A line separator will be appended to each input.
8
* @param inputs String inputs to be entered to stdin.
9
*/
10
public void setStdInput(String... inputs) {}
11
12
/**
13
* Returns all the outputs printed to standard output after the last reset.
14
* If you do not use `resetStdOut()`,
15
* this may return outputs from other test cases.
16
*/
17
public String getOutput() {}
18
19
/**
20
* Reset (clear) the output printed to stdout.
21
*/
22
public void resetStdOut() {}
23
}
Copied!

EvaluationHelper

Here are all the details of EvaluationHelper class to help you test method and field declarations.
1
package com.udemy.ucp;
2
3
public class EvaluationHelper {
4
5
/**
6
* Check if a method is declared in a class
7
* @param obj Instance of the class
8
* @param methodName Name of the method to be checked
9
* @param parameterTypes Types of parameters the method expects such as int.class
10
*/
11
public boolean isMethodDeclared(Object obj, String methodName,
12
Class<?>... parameterTypes)
13
14
/**
15
* Checks whether a field is declared in a class
16
* @param obj Instance of the class
17
* @param fieldName Name of the field to be checked
18
*/
19
public boolean isFieldDeclared(Object obj, String fieldName)
20
21
/**
22
* Checks whether a field with specific type is declared in a class
23
* @param obj Instance of the class
24
* @param fieldName Name of the field to be checked
25
* @param fieldType Type of the field
26
*/
27
public boolean isFieldDeclared(Object obj, String fieldName, Class<?> fieldType)
28
29
/**
30
* Return the value of a field from a given instance
31
* @param obj Instance that contains the field
32
* @param fieldName Name of the field whose value will be returned
33
*/
34
public Object getFieldValue(Object obj, String fieldName)
35
36
/**
37
* Return the type of a field in a class
38
* @param obj Instance of the class that contains the field
39
* @param fieldName Name of the field whose value will be returned
40
*/
41
public Class<?> getFieldType(Object obj, String fieldName)
42
43
/**
44
* Checks whether a field has private modifier or not
45
* @param obj Instance of the class
46
* @param fieldName Name of the field to be checked
47
*/
48
public boolean isFieldPrivate(Object obj, String fieldName)
49
50
/**
51
* Checks whether a field has protected modifier or not
52
* @param obj Instance of the class
53
* @param fieldName Name of the field to be checked
54
*/
55
public boolean isFieldProtected(Object obj, String fieldName)
56
57
/**
58
* Checks whether a field has public modifier or not
59
* @param obj Instance of the class
60
* @param fieldName Name of the field to be checked
61
*/
62
public boolean isFieldPublic(Object obj, String fieldName)
63
64
/**
65
* Checks whether a field has static modifier or not
66
* @param obj Instance of the class
67
* @param fieldName Name of the field to be checked
68
*/
69
public boolean isFieldStatic(Object obj, String fieldName)
70
71
/**
72
* Checks whether a field has final modifier or not
73
* @param obj Instance of the class
74
* @param fieldName Name of the field to be checked
75
*/
76
public boolean isFieldFinal(Object obj, String fieldName)
77
}
Copied!
Last modified 1yr ago