JUnit set up test case - java

I have never used JUnit before and I'm having some trouble setting up the tests. I have a Java project and a package, both named 'Project1' with one class which I'm trying to test called 'Module'. At the moment I'm just wanting to check if the values are correct.
Module class
package Project1;
//This class represents a module
public class Module {
public final static int MSC_MODULE_PASS_MARK = 50;
public final static int UG_MODULE_PASS_MARK = 40;
public final static int MSC_MODULE_LEVEL = 7;
public final static int STAGE_3_MODULE_LEVEL = 6;
private String moduleCode;
private String moduleTitle;
private int sem1Credits;
private int sem2Credits;
private int sem3Credits;
private int moduleLevel;
public Module(String code, String title, int sem1, int sem2, int sem3, int level)
{
moduleCode = code;
moduleTitle = title;
sem1Credits = sem1;
sem2Credits = sem2;
sem3Credits = sem3;
moduleLevel = level;
}
//method to return the module code
public String getCode()
{
return moduleCode;
}
//INSERT A BUNCH OF GET METHODS
}
Test case
Here is where I get lost. I'm trying to give some dummy values to test but I'm not sure how to pass the instance of Module to test.
package Project1;
import static org.junit.Assert.*;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
public class TestCase {
#BeforeClass
public static void setUpBeforeClass() throws Exception {
}
#Before
public void setUp() throws Exception {
Module csc8001 = new Module("CSC8001", "Programming and data structures", 20, 0, 0, 7);
}
#Test
public void test() {
if (csc8001.getCode() == "CSC8001") {
System.out.println("Correct");
}
else{
fail("Not yet implemented");
}
}
}

Make your Module variable an instance variable in your test class, instead of a local variable in a method. Then the #Before method will just initialize the variable, not declare it too. Then it will be in scope in any #Test method.
Incidentally, compare your string contents with String's equals method, not ==.

import static org.junit.Assert.assertEquals;
public class TestCase {
private final Module csc8001 = new Module("CSC8001", "Programming and data structures", 20, 0, 0, 7);
#Test
public void testGetCode() {
assertEquals("Some error message", "CSC8001", csc8001.getCode()) ;
}
}

Always use equals:
if (csc8001.getCode().equals("CSC8001")) {
furthermore declare csc8001 as a class member.
public class TestCase {
private Module csc8001;
and
#Before
public void setUp() throws Exception {
csc8001 = new Module("CSC8001", "Programming and data structures", 20, 0, 0, 7);
}

Make your Module an instance variable. Remember that for each separate #Test method, JUnit will create a separate instance of your test class and run all of your #Before methods on it. Though you can instantiate your system under test in the same place you declare it, it may be advantageous to keep it in #Before as you have it.
public class TestCase {
private Module csc8001;
#Before public void setUp() throws Exception {
csc8001 = new Module("CSC8001", "Programming and data structures", 20, 0, 0, 7);
}
#Test public void test() { /* ... */ }
}
You can also use assertEquals to check equality, which will automatically fail with a clear message if the parameters don't match.
#Test
public void codeShouldEqualCSC8001() {
assertEquals("CSC8001", csc8001.getCode());
}
See assertEquals and more at the org.junit.Assert documentation.
p.s. Remember that the prefix test and the name setUp are holdovers from JUnit 3, and that using JUnit4 or better (with annotations like #Before and #Test) you are free to add multiple #Before and #After methods and give all your methods unconstrained names.

Related

How to check that a method is not being called using JUnit Mockito Verify

I have a class for which I am writing a JUnit test. I am trying to test if a particular method is never called.
public class CountryProcess extends AbstractCountryProcess {
private static final Logger log = LoggerFactory.getLogger(CountryProcessor.class);
private static final Long MAX_FILE = 20l;
#Override
protected boolean processCountry(Region region, City city) {
Long maxFile = region.getRequiredLongValue(SIZE);
if (maxFile < MAX_FILE) {
cntDao.addCountryLandMark(city);
}
else {
log.warn("File size was big");
}
return true;
}
And the test class is:
public class CountryProcessTest {
#Rule
public final JUnitRuleMockery context = new JUnitRuleMockery();
private final CntDao cntDao = context.mock(CntDao.class);
#Before
public void setup() {
Injector injector = Guice.createInjector(new AbstractModule() {
#Override
protected void configure() {
bind(cntDao.class).toInstance(cntDao);
}
});
}
#Test
public void shouldIgnoreIfFileSizeBiggerThanPermitted() {
//some code to make it trigger ELSE statement above...
verify(cntDao, never()).addCountryLandMark(anyString());
}
}
But this returns the following error:
org.mockito.exceptions.misusing.NotAMockException:
Argument passed to verify() is of type $Proxy4 and is not a mock!
Make sure you place the parenthesis correctly!
See the examples of correct verifications:
verify(mock).someMethod();
verify(mock, times(10)).someMethod();
verify(mock, atLeastOnce()).someMethod();
Any idea how I can fix this in the current context. Please give an example using current code so I get a better idea?
You are mixing two mocking frameworks:
jMock - JUnitRuleMockery
Mockito - verify method
Clearly, they are not compatible with each other.
Your verify call looks ok, I believe it will work as soon as it receives a mock created with Mockito (Use Mockito.mock(CntDao.class))
As an alternative to never you can use Mockito.verifyNoMoreInteractions or Mockito.verifyZeroInteractions, but they are less specific.
In addition to the answer from #Lesiak, here is a reproducible example based on your code with both conditions tested and BDD implementation as well (commented out).
#ExtendWith(MockitoExtension.class)
class CountryProcessTest {
#Mock CountryDAO cntDao;
#Mock
Region region;
#Mock
City city;
#InjectMocks
CountryProcess countryProcess;
#Test
void processCountryLargeSize() {
// given
given(region.getRequiredLongValue()).willReturn(100L);
// when
countryProcess.processCountry(region, city);
// then
verifyNoInteractions(cntDao);
// then(cntDao).shouldHaveNoInteractions(); // BDD implementation
}
#Test
void processCountrySmallSize() {
// given
given(region.getRequiredLongValue()).willReturn(10L);
// when
countryProcess.processCountry(region, city);
// then
verify(cntDao).addCountryLandMark(city);
verifyNoMoreInteractions(cntDao);
// then(cntDao).should().addCountryLandMark(any()); // BDD implementation
// then(cntDao).shouldHaveNoMoreInteractions(); // BDD implementation
}
}
The rest of the classes here are provided for reference.
Region
public class Region {
private int size;
public Long getRequiredLongValue() {
return Integer.toUnsignedLong(size);
}
}
AbstractCountryProcess
public abstract class AbstractCountryProcess {
CountryDAO cntDao;
protected abstract boolean processCountry(Region region, City city);
}

How to mock another class method call from the method being tested using powermock-easymock?

I'm using easymock and powermock to write unit test case for the below isRegisteredUSer() of Class B. How to mock getUserInformation() of Class A and return a mocked UserAccessBean?
class A{
private int userId;
A(int userId){
this.userId = userId;
}
public UserAccessBean getUserInformation(){
UserAccessBean userAB = new USerAccessBean().findByUserId(userId);
return userAB;
}
}
Class B{
public static boolean isRegisteredUSer(int userId){
A a = new A(userId);
UserAccessBean userAB = a.getUserInformation();
if(userAB.getUserType().equals("R")){
return true;
}
return false;
}
JUnit
public class BTest extends EasyMockSupport{
UserAccessBean userAB = null;
A a = null;
int userId = 12345;
#Before
public void setUp() throws Exception {
userAB = new UserAccessBean();
}
#Test
public void when_UserDesctiptionIsR_Expect_True_FromIsRegisteredUser() throws Exception{
//data setup
userAB.setDescription("R");
A a = new A(12345);
EasyMock.expect(a.isRegisteredUser()).andReturn(userAB);
PowerMock.replayAll();
Boolean flag = B.isRegisteredUser(userId);
assertEquals(flag, true);
PowerMock.verifyAll();
}
}
Even If I use EasyMock.expect() to mock getUserInformation() method call, my console is going inside getUserInformation() when I run my JUnit.
Can someone please help me to mock another class functions method (Class A's getUserInformation) call from the method (Class B's isRegisteredUSer) being tested?
Please, next time copy actual working code. Your code has many typos and anomalies that makes it hard to workaround.
Nevertheless, I think you want a normal EasyMock for A and a mock on new for B. The code below should answer your question
#RunWith(PowerMockRunner.class)
#PrepareForTest({A.class, B.class})
public class BTest extends EasyMockSupport {
UserAccessBean userAB = new UserAccessBean();
A a;
int userId = 12345;
#Test
public void when_UserDesctiptionIsR_Expect_True_FromIsRegisteredUser() throws Exception {
//data setup
userAB.setDescription("R");
A a = createMock(A.class);
expect(a.getUserInformation()).andReturn(userAB);
replayAll();
PowerMock.expectNew(A.class, userId).andReturn(a);
PowerMock.replay(A.class);
Boolean flag = B.isRegisteredUser(userId);
assertEquals(flag, true);
PowerMock.verifyAll();
verifyAll();
}
}
I will however highly recommend A to be injected into B and to get rid of the static method. That will get rid of PowerMock and simplify the code.

JUnitParams - executing separate methods before test

#RunWith(JUnitParamsRunner.class)
public class MySimpleTest {
private MyRec rec;
private Matrix matrix;
#Before
public void createRecognizerBeforeEveryExecution() {
rec = new MyRec();
matrix = MatrixUtils.createMatrixWithValues();
}
public static Iterable<Object[]> data() {
return Arrays.asList(
new Object[]{"expectedvalue1", "input1"},
new Object[]{"expectedvalue2", "input2"}
);
}
#Test
#Parameters(method = "data")
public void test1(String output, String input) {
rec.fun1(matrix);
assertEquals(output, rec.someFunction(input));
}
public static Iterable<Object[]> data2() {
return Arrays.asList(
new Object[]{"expectedothervalue1", "input1"},
new Object[]{"expectedothervalue2", "input2"}
);
}
#Test
#Parameters(method = "data2")
public void test2(String output, String input) {
rec.fun1(matrix);
rec.fun2(matrix);
assertEquals(output, rec.someFunction(input));
}
}
I'm trying to find out what is the proper way to make this test. I'd like to use parametrized test, because it's really convenient way.
So as you can see, in every test function I call some function (fun1 and fun2). But I need to call it only once per every test (e.g. before each parametrized test execution).
Is there any way to tell JUnitParams that it should execute other function before executing all of parametrized tests?
I can't use #Before annotation, because as you can see in test1 I'm not using fun2. It think it should be executed by separate function.
Solution 1:
As fun[1|2] does not depend on internal test state, try to place their invocations inside data and data2 methods accordingly.
public static Iterable<Object[]> data() {
rec.fun1(matrix);
return Arrays.asList(
new Object[]{"expectedvalue1", "input1"},
new Object[]{"expectedvalue2", "input2"}
);
}
public static Iterable<Object[]> data2() {
rec.fun1(matrix);
rec.fun2(matrix);
return Arrays.asList(
new Object[]{"expectedvalue1", "input1"},
new Object[]{"expectedvalue2", "input2"}
);
}
Solution 2:
Spliting test cases is not a best practice. Your test are harder to maintain. Flow is far more complicated. There is also a risk your tests start depends on each other. Duplication in tests sometimes is simply better.
PS:
If you are using Strings as test method parameters it's better to pass them exactly like in 25th line of this file:
https://github.com/Pragmatists/JUnitParams/blob/master/src/test/java/junitparams/usage/SamplesOfUsageTest.java instead of special methods.
#Test
#Parameters({"AAA,1", "BBB,2"})
public void paramsInAnnotation(String p1, Integer p2) { }
I decided to use TestNG to resolve this problem (code just to show my train of thought):
import org.testng.Assert;
import org.testng.annotations.*;
import java.lang.reflect.Method;
public class TempTest {
private Integer number;
#BeforeMethod
public void init(Method m) {
number = 5;
switch(m.getName()) {
case "test2":
fun(10);
fun2(5);
break;
case "test1":
fun(10);
break;
}
}
public void fun(int value) {
number += value;
}
public void fun2(int value) {
number -= value;
}
#Test
public void test1() {
Assert.assertEquals(new Integer(15), number);
}
#Test
public void test2() {
Assert.assertEquals(new Integer(10), number);
}
#Test
public void test3() {
Assert.assertEquals(new Integer(5), number);
}
}

Verify method in constructor was called

I have a constructor that calls a method, like this:
public Foo(boolean runExtraStuff) {
if (runExtraStuff){
doExtraStuff();
}
}
The doExtraStuff() method is running some additional commands that are not easily mocked themselves (things like database checks to initialize some variables). Perhaps it would be better for the constructor to not do this, but this is the code I have to work with at the moment.
I would like to create a unit test to make sure that doExtraStuff() is called when the boolean runExtraStuff is true and does not run when the boolean is false. I am using JMockit.
However, I'm not sure how to make this happen. Normally I would use a Verifications on a mocked object, but since I am testing the constructor, I can't use a mocked object in this way. So how can I verify that a method within a constructor was called?
It's easy enough, even if it requires partial mocking:
#Test
public void runsSetupWhenRequestedOnFooInitialization()
{
// Partially mocks the class under test:
new Expectations(Foo.class) {};
final Foo foo = new Foo(true);
// Assuming "setup" is not private (if it is, use Deencapsulation.invoke):
new Verifications() {{ foo.setup(); }};
}
#Test
public void doesNotRunSetupWhenNotRequestedOnFooInitialization()
{
new Expectations(Foo.class) {};
final Foo foo = new Foo(false);
new Verifications() {{ foo.setup(); times = 0; }};
}
Of course, it would probably be better to avoid mocking in a case like this; instead, the test should check the state of the object through getters or other available methods, if at all possible.
Well, the straightforward answer doesn't use JMockit at all..
in src/main/java/example..
package example;
public class Foo {
private boolean setupRan = false;
public Foo(boolean runSetup) {
if (runSetup) setup();
}
public void setup() {
setupRan = true;
}
public boolean getSetupRan() {
return setupRan;
}
}
in src/test/java/example..
package example;
import static org.assertj.core.api.Assertions.*;
import org.junit.Test;
public class FooTest {
private Foo testSubject;
#Test
public void should_run_setup() {
testSubject = new Foo(true);
assertThat(testSubject.getSetupRan()).isTrue();
}
#Test
public void should_not_run_setup() {
testSubject = new Foo(false);
assertThat(testSubject.getSetupRan()).isFalse();
}
}
I'll go out on a limb and guess that you are interested in a partial mock here:
in src/main/java/example..
package example;
public class Foo1 {
public Foo1(boolean runSetup) {
if (runSetup) setup();
}
public void setup() {
System.out.println("in setup()");
}
}
in src/test/java/example..
package example;
import static org.assertj.core.api.Assertions.*;
import mockit.Expectations;
import mockit.Mocked;
import org.junit.Test;
public class Foo1Test {
// hateful partial mocking of test subject!
#Mocked({"setup()"})
private Foo1 testSubject;
#Test
public void should_run_setup() {
new Expectations() {{
testSubject.setup(); // setup() is called
}};
testSubject = new Foo1(true);
}
#Test
public void should_not_run_setup() {
new Expectations() {{
testSubject.setup(); times = 0;
}};
testSubject = new Foo1(false);
}
}
EDIT 1: Note that you won't see the println output since the method was mocked.
EDIT 2: Set expectations for invocations of testSubject.setup() to times = 0 in second test

Passing parameter to #Before setup in jUnit test [duplicate]

This question already has answers here:
Is it possible to use different #Before #After for each test case in JUnit?
(2 answers)
Closed 8 years ago.
Is there any way to avoid calling populateRandomData() method at the begining of each test without having a fixed parameter 100. I need to call the same method to setup data before execution of each test but I need to change the number of test data entries e.g. 100 in each case .
public class Tester
{
#Before
public void setUp() {
populateRandomData(100)
}
#Test
public void testMethod() {
}
private void populateRandomData(n){
//n times insert random data in table.
}
}
You can create Parameterized JUnit Test which allows you to add number of parameters you want to pass in unit test case. Have a look at example tutorial Create Parameterized Test Case.
OR
#Rule, using this annotations on your test methods to parameterize the execution of your rules makes it even more useful. Taken from JUnit 4.7 #Rules
EDIT :
Example of Using #Rule :
Below is the class which allows you to initialize different value of num variable which will be used in test method :
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;
public class Test1 implements TestRule {
private final int num;
public Test1(int num) {
this.num = num;
}
public int getNum() {
return num;
}
public class Test1Statement extends Statement {
private final Statement statement;
public Test1Statement(Statement statement, int num) {
this.statement = statement;
}
#Override
public void evaluate() throws Throwable {
statement.evaluate();
}
}
#Override
public Statement apply(Statement statement, Description description) {
return new Test1Statement(statement, num);
}
}
The class below is the actual test case class. It contains JUnit test cases & set value of num variable in test method.
import org.junit.Rule;
import org.junit.Test;
public class RuleNumberTester {
#Rule
public Test1 test = null;
#Rule
public Test1 test1 = null;
#Test
public void num1Test() {
test = new Test1(111);
System.out.println("Num 1 : " + test.getNum());
}
#Test
public void num2Test() {
test1 = new Test1(222);
System.out.println("Num 2 : " + test1.getNum());
}
}
Output :
Test cases are executed successfully & shows the values of num variable which was initialized in test methods on console.
Num 1 : 111
Num 2 : 222
I suppose you could use a #Rule to ensure populateRandomData() is called each time with the correct parameters.
However, this gets ugly quickly since you then need to maintain a list of test method names.
private static final Map<String, Integer> dataCounts = new HashMap<>();
static {
// list (or otherwise obtain) counts here
dataCounts.put("testMethod", 100);
}
#Rule
public TestWatcher watcher = new TestWatcher() {
#Override
protected void starting(Description description) {
Integer count = dataCounts.get(description.getMethodName());
assertNotNull(count);
populateRandomData(count.intValue());
};
};

Categories