Junit testing for a boolean method - java

I have problem writing a testcase to this method below: EvenNum(double)
public class OddEven {
/**
* #param args
*/
public boolean evenNum(double num)
{
if(num%2 == 0)
{
System.out.print(true);
return true;
}
else
{
System.out.print(false);
return false;
}
}
This is the testcase I wrote but I think I have an inheritance problem or a logical problem in this test case. Should be a very simple one but can't figure out. Here is the code I wrote:
import static org.junit.Assert.*;
import org.junit.Test;
public class OddEvenTest {
#Test
public void testEvenNum() {
boolean ans = true;
boolean val;
double num= 6;
val = OddEven.EvenNum(num) // cant inherit the method dont know why???
assertEquals(ans,val);
}
}

You have a number of issues:
you are attempting to call a non-static method statically
method names in java are case sensitive and you've mixed up the case.
I corrected some things for you and just verified the code below:
OddEven.java:
public class OddEven {
public boolean evenNum(double num)
{
if(num%2 == 0)
{
System.out.print(true);
return true;
}
else
{
System.out.print(false);
return false;
}
}
}
OddEvenTest.java
import static org.junit.Assert.*;
import org.junit.Test;
public class OddEvenTest {
#Test
public void testEvenNum() {
boolean ans = true;
boolean val;
double num = 6;
OddEven oddEven = new OddEven();
val = oddEven.evenNum(num);
assertEquals(ans,val);
}
}
Assuming the calls to System.out.println() in OddEven are strictly for debugging, the whole thing could be collapsed down to:
OddEven.java
public class OddEven {
public boolean evenNum(double num) {
return num%2 == 0;
}
}
OddEvenTest.java
import static org.junit.Assert.*;
import org.junit.Test;
public class OddEvenTest {
#Test
public void testEvenNum() {
OddEven oddEven = new OddEven();
assertTrue(oddEven.evenNum(6));
assertFalse(oddEven.evenNum(5));
}
}
The code is now shorter and the unit test even covers an odd case for good measure.

Two things :
You are invoking a non-static method statically. The method should be declared static:
public static boolean evenNum(double num) {
}
You didn't type the name of the method correctly. Look closely. Also consider renaming it something more readable like, isEven(...)

This seems like testing gone mad to me, and programming gone mad too. All the method does is evaluate num % 2 == 0. You may as well just code that everywhere required and throw away both the method and its tests. If you must keep the method, it relies on a mathematical identity, you don't need to test those. You may as well test 1+1==2.

Related

Is there a different way to write get methods in Java?

I know that we can retrieve a variable's value by simply writing get methods and return var;. However, is there another way to write a get method to return information on the fields instead? If so, how does one access it. For example, if I have a planeNumber and I want to check it against another object's planeNumber, is there a way to use a boolean to check instead of writing public int getPlaneNumber()?
Seems like you are wanting to implement the Comparable interface? https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html
That is it looks like you have an attribute, planeNumber, that you want to use to compare the classes?
Maybe you want something like this
import java.util.Comparator;
import java.util.Objects;
public class Airplane implements Comparable<Airplane> {
private final int planeNumber;
public Airplane(final int planeNumber) {
this.planeNumber = planeNumber;
}
public final int getPlaneNumber() {
return planeNumber;
}
#Override
public int compareTo(final Airplane o) {
return Objects.compare(this, o, Comparator.comparing(Airplane::getPlaneNumber));
}
public static void main(final String... args) {
System.out.println(new Airplane(1).compareTo(new Airplane(2)));
System.out.println(new Airplane(100).compareTo(new Airplane(100)));
System.out.println(new Airplane(1000).compareTo(new Airplane(100)));
}
}
-1
0
1
You could add a method comparing the field values to your class like this (omitting null check in the methods):
class Scratch {
public static void main(String[] args) {
ObjectWithPlaneNumber o1 = new ObjectWithPlaneNumber(42);
ObjectWithPlaneNumber o2 = new ObjectWithPlaneNumber(42);
ObjectWithPlaneNumber o3 = new ObjectWithPlaneNumber(11);
System.out.println(o1.hasSamePlaneNumber(o2));
System.out.println(o1.hasSamePlaneNumber(o3));
}
static class ObjectWithPlaneNumber {
private final int planeNumber;
public ObjectWithPlaneNumber(int planeNumber) {
this.planeNumber = planeNumber;
}
public boolean hasSamePlaneNumber(ObjectWithPlaneNumber other) {
return this.planeNumber == other.planeNumber;
}
}
}

How to run class if test case failed in testNG

I have an issue that I am facing,
I have a class with multiple test cases and I am using test ng with java and selenium.
Is there a possibility that if a test case failed, testNG will run the entire class again?
not the test.
since there are a priority and navigation between pages.
Is there a way to run the entire class that is failed again? I just saw to rerun the test, and it is useless to me.
regards
If I understood you right this is the solution which you needed
import org.testng.IRetryAnalyzer;
import org.testng.ITestResult;
public class Retry implements IRetryAnalyzer {
private int count = 0;
private static int maxTry = 3;
public boolean retry(ITestResult iTestResult) {
if (!iTestResult.isSuccess()) {
if (count < maxTry) {
count++;
iTestResult.setStatus(ITestResult.SUCCESS);
return true;
} else {
iTestResult.setStatus(ITestResult.FAILURE);
}
} else {
iTestResult.setStatus(ITestResult.FAILURE);
}
return false;
}
}
Then your all tests methods should be like this:
#Test(retryAnalyzer=Retry.class)
And you should add the BeforeSuite
#BeforeSuite(alwaysRun = true)
public void beforeSuite(ITestContext context) {
for (ITestNGMethod method : context.getAllTestMethods()) {
method.setRetryAnalyzerClass(Retry.class);
}
}

Simple Pass Fail Java program

I am trying to write a Java function based off of the following question:
Write a program called CheckPassFail which prints "PASS" if the int variable "mark" is more than or equal to 50; or prints "FAIL" otherwise. The program shall always print “DONE” before exiting.
This is what I have so far:
import java.util.*;
import java.lang.*;
import java.io.*;
class CheckPassFail(){
int m;
public void GetGrade(int mark){
m = mark;
}
public void GradeCheck(int mark){
if(mark >= 50){
system.out.println("Pass");
}
else{
system.out.println("Fail");
}
public static void main(String[] args){
CheckPassFail grade = new GetGrade(66);
grade.GradeCheck(66);
}
}
I believe my issue has to do with the GetGrade class? I feel as if setting m = mark is unnecessary for this program. Please let me know if you see any other errors. Thank you.
Critical problems (these are preventing your program from compiling):
Your code is missing the closing brace } in the GradeCheck method.
There must not be parenthesis in class declarations, as in class CheckPassFail {
Java is case-sensitive. You must use System, not system, as in System.out.println();
Technical explanation: System refers to the builtin class java.lang.System. All java.lang classes are automatically available without you needing to import them.
GradeCheck is a method, not a class. You cannot create a new instance of it, or use the new operator with it, as you did with new GetGrade(66);
Non-critical (but nevertheless important) problems:
You seem to think that GetGrade is a constructor. It is not. That is not how constructors work. That is not how classes work. That is not how Java works.
The variable m is declared and assigned to, but never used.
Your program does not print "DONE" after executing, which was a requirement.
All of your imports are unused. You should not import extraneous packages.
The class CheckPassFail should be public. Most Java classes should be public.
Your indentation is inconsistent and makes your code less readable.
Cleaned-up version of your code:
public class CheckPassFail {
public int mark;
public CheckPassFail(int mark) {
this.mark = mark;
}
public void checkGrade() {
if(mark >= 50) {
System.out.println("PASS");
} else {
System.out.println("FAIL");
}
}
public static void main(String[] args) {
CheckPassFail checker = new CheckPassFail(66);
checker.checkGrade();
System.out.println("DONE");
}
}
GetGrade is not a class, it's a function. Therefore, it should be called without the 'new' keyword.
Class declaration syntax is wrong, there shouldn't be any parenthesis.
Considering what GradeCheck function is doing, GetGrade function is useless (unless you need it somewhere else).
'system' should be 'System' (in-built class from java.lang package).
Class names should start with upper-case letters and function names should start with lower-case letters (standard).
class CheckPassFail {
public void gradeCheck(int mark) {
if(mark >= 50) {
System.out.println("Pass");
}
else {
System.out.println("Fail");
}
}
public static void main(String[] args) {
CheckPassFail check = new CheckPassFail();
check.gradeCheck(66);
}
}
class CheckPassFail
{
int m;
CheckPassFail(int mark){
m = mark;
}
public void gradeCheck(int mark){
if(mark >= 50){
System.out.println("Pass");
}
else{
System.out.println("Fail");
}}
public static void main(String[] args) {
CheckPassFail grade = new CheckPassFail(66);
grade.gradeCheck(66);
}}
class CheckPassFail {
public void gradeCheck(int mark) {
if(mark >= 50) {
System.out.println("Pass");
}
else {
System.out.println("Fail");
}
}
public static void main(String[] args) {
CheckPassFail grade = new CheckPassFail();
grade.gradeCheck(66);
}
}

JUnit: setUp and tearDown methods not working as expected

I was trying to develop some code using TDD, but stumbled on a weird behavior: setUp and tearDown doesn't seem to be "cleaning up" after each test is executed. I expected each test (marked with #Test annotation) to be executed at a random order, one after the other, without influencing each other. With that in mind, I don't understand what is happening as it seems like one specific test (testaSomarMao) is influencing another specific test (testaSplit). The testaSplit test is failling on the first assert: I expected value 6, but I'm getting 9. Anybody can explain me what is going on?
JogadorTest.java
import static org.junit.Assert.*;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
public class JogadorTest{
private static Jogador p1;
public JogadorTest(){
}
#Before
public void setUp(){
p1 = new Jogador();
}
#After
public void tearDown(){
p1 = null;
}
#Test
public void testaGetNome(){
assertEquals(null, p1.getNome());
}
#Test
public void testaGetPontos(){
assertEquals(0, p1.getPontos());
}
#Test
public void testaSetNome(){
p1.setNome("Lucas");
assertEquals("Lucas", p1.getNome());
}
#Test
public void testaSomarMao(){
p1.comprarCarta(1);
assertEquals(3, p1.somarMao(1));
}
#Test
public void testaSplit(){
p1.comprarCarta(1);
p1.comprarCarta(1);
assertEquals(6, p1.somarMao(1));
p1.split();
assertEquals(p1.somarMao(1), p1.somarMao(2));
}
}
Jogador.java
public class Jogador {
private static String nome;
private int pontos;
private static int mao[] = new int[13];
private static int mao2[] = new int[13];
public void parar() {
}
public void setNome(String novoNome){
nome = novoNome;
}
public static int getPontos() {
return 0;
}
public static void split() {
//Usamos mao2 para garantir que soh ocorra um split.
if(mao[0] == mao[1] && mao2[0] == 0){
mao2[0] = mao[1];
mao[1] = 0;
}
}
public void fecharJogo() {
}
public String getNome() {
return nome;
}
public static int somarMao(int maoEscolhida){
int soma = 0;
int cartasNaMao[];
if(maoEscolhida == 2)
cartasNaMao = mao2;
else
cartasNaMao = mao;
for(int i = 0; i < cartasNaMao.length; i++)
soma += cartasNaMao[i];
return soma;
}
public static void comprarCarta(int maoEscolhida){
int carta = 3; // random futuramente
int cartasNaMao[];
if(maoEscolhida == 2)
cartasNaMao = mao2;
else
cartasNaMao = mao;
for(int i = 0; i < cartasNaMao.length; i++){
if(cartasNaMao[i] == 0) {
cartasNaMao[i] = carta;
break;
}
}
}
}
The underlying reason for your problem is, as pointed out by Thevenin, the use of static variables for mao[] and mao2[]
You will also need to remove static from methods comprarCarta and somarMao. You will not need it after all variables referenced inside are not static anymore. From the test it is obvious you are not using them in the way static methods are invoked usually, i.e Jogador.comprarCarta(1) instead of p1.comprarCarta(1).
My guess is you created those methods static and compiler then complained that your variables are not static and cannot be accessed, so you changed the variables as well.
Actually the use of static will cause you issues with other parts of your program as well - you better change nome variable to not be static. Same applies for getPontos() method - if you try to return pontos there instead of 0 you will get a compiler error that pontos is not static.
As you are confusing the use static in general take a look at this great explanation of what is static, when you have the time :)
Static variables - what are they?
In comprarCarta() you are modifying mao or mao2 which are static arrays. Any changes you make to these arrays will persist across all instances of Jogador.
Since this is not what you expect I suspect that you may not want these to be static.

mockito verifying polymorphic methods

I'm trying to verify call to a polymorphic method using mockito, and am confused about what the best way forward is.
Example Class
public class Library {
public boolean foo() {
return true;
}
public boolean foo(String s) {
return true;
}
public boolean foo(Integer s) {
return true;
}
}
The test class using mockito(ignore the fact that in LibraryTest class, Library is not the class-under-test, but rather I'm mocking it)
import org.junit.Test;
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
public class LibraryTest {
#Test public void testFoo1() {
Library mockLibrary = mock(Library.class);
mockLibrary.foo("Hi");
verify(mockLibrary).foo(any());
}
#Test public void testFoo2() {
Library mockLibrary = mock(Library.class);
verify(mockLibrary, never()).foo(any());
}
}
So both the verify statements don't compile, with the error "The method foo(String) is ambiguous for the type Library".
The error kind of makes sense, any() tries to return a captor based on the type of the argument but the argument could be Integer or String or void.
What I want to achieve is that in both the tests, a call to any of the foo methods is counted by the verify. In other words the first verify call should succeed if I called any of the foo methods and the second verify should fail if I call any of the foo methods.
Is there a way to make this happen?
You can use isA matcher
verify(mockLibrary).foo(isA(Integer.class));
verify(mockLibrary).foo(isA(String.class));
and btw use Mockito.spy instead of Mockito.mock when you only want to see if some methods have been called on the class under test
EDIT with example (written in few minutes, don't mind the code:)) based on the new op details.
public static class Library {
public boolean foo() {
return true;
}
public boolean foo(String s) {
return true;
}
public boolean foo(Integer s) {
return true;
}
public String x(){
return "";
}
public void y(){
return;
}
}
public static class ResponseProvider {
public boolean result;
}
#Test
public void testFoo1() {
final ResponseProvider provider = new ResponseProvider();
provider.result = false;
Library lib = Mockito.mock(Library.class, new Answer<Object>() {
#Override
public Object answer(InvocationOnMock invocation) throws Throwable {
if ((invocation.getMethod().getName().equals("foo"))) {
provider.result = true;
return true;
}
return invocation.callRealMethod();
}
});
//lib.foo();
//lib.x();
//lib.y();
assertTrue(provider.result);
}
First of all, You are mocking the same class which you are testing. Thats not advisable but still
Its giving this exception because mockito doesn't know which method you are verifying among the foo methods. If you want to make sure the method you invoked is called with the right value, you can either use isA(ClassName) matcher or use can use ArgumentCaptor.
Example of ArgumentCaptor
#Test public void testFoo1() {
Library mockLibrary = mock(Library.class);
mockLibrary.foo("Hi");
ArgumentCaptor<String> stringCaptor = ArgumentCaptor.forClass(String.class);
verify(mockLibrary).foo(stringCaptor.capture());
String actualArgument = stringCaptor.getValue();
assertEquals(actualArgument, "Hi");
}

Categories

Resources