Mockito and Junit tests run in isolation but fail when run together - junit

I have been encountering a strange issue. My test cases have one failing test, the welcometest. However, if I run the same in isolation, it runs perfectly. I am new to JUnit and have no idea why this could happen.
package com.twu.biblioteca;
org.junit.After;
import org.junit.Before;
import org.mockito.Mockito;
import org.mockito.Mockito.*;
import org.junit.Test;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.*;
public class ExampleTest {
#Test
public void welcometest() {
BibliotecaApp test = mock(BibliotecaApp.class);
BibliotecaApp.IntegerAsker asker = mock(BibliotecaApp.IntegerAsker.class);
test.welcome(asker);
verify(asker).printLine("**** Welcome Customer! We are glad to have you at Biblioteca! ****");
}
#Test
public void addBooksTest() {
BibliotecaApp test = mock(BibliotecaApp.class);
BibliotecaApp.IntegerAsker asker = mock(BibliotecaApp.IntegerAsker.class);
test.addBooks();
assertEquals("Head First Java", test.booksList[1].name);
assertEquals("Dheeraj Malhotra", test.booksList[2].author);
assertEquals(2009, test.booksList[3].publication);
}
#Test
public void CustomersaddedTest() {
BibliotecaApp test = mock(BibliotecaApp.class);
BibliotecaApp.IntegerAsker asker = mock(BibliotecaApp.IntegerAsker.class);
test.addCustomers();
assertEquals("Ritabrata Moitra", test.customerList[1].name);
assertEquals("121-1523", test.customerList[2].libraryNumber);
assertEquals("0987654321", test.customerList[3].number);
}
#Test
public void addMoviesTest() {
BibliotecaApp test = mock(BibliotecaApp.class);
BibliotecaApp.IntegerAsker asker = mock(BibliotecaApp.IntegerAsker.class);
test.addMovies();
assertEquals("Taken", test.moviesList[1].name);
assertEquals("Steven Spielberg", test.moviesList[2].director);
assertEquals(2004, test.moviesList[3].year);
}
#Test
public void getBoundIntegerFromUserTest() {
BibliotecaApp test = mock(BibliotecaApp.class);
BibliotecaApp.IntegerAsker asker = mock(BibliotecaApp.IntegerAsker.class);
when(asker.ask("Enter your choice. ")).thenReturn(99);
when(asker.ask("Select a valid option! ")).thenReturn(1);
BibliotecaApp.getBoundIntegerFromUser(asker, "Enter your choice. ", 1, 2);
verify(asker).ask("Select a valid option! ");
}
#Test
public void mainMenuTest() {
BibliotecaApp test = mock(BibliotecaApp.class);
BibliotecaApp.IntegerAsker asker = mock(BibliotecaApp.IntegerAsker.class);
when(asker.ask("Enter your choice. ")).thenReturn(test.numberOfMainMenuOptions);
test.mainMenu(asker);
verify(test).mainMenuaction(3, asker);
}
#Test
public void checkoutTest() {
BibliotecaApp test = mock(BibliotecaApp.class);
BibliotecaApp.IntegerAsker asker = mock(BibliotecaApp.IntegerAsker.class);
when(asker.ask("Enter the serial number of the book that you want to checkout")).thenReturn(2);
test.addBooks();
test.checkout(asker);
assertEquals(0, test.booksList[2].checkoutstatus);
}
#Test
public void returnTest() {
BibliotecaApp test = mock(BibliotecaApp.class);
BibliotecaApp.IntegerAsker asker = mock(BibliotecaApp.IntegerAsker.class);
when(asker.ask("Enter the serial number of the book that you want to return")).thenReturn(2);
test.addBooks();
test.booksList[2].checkoutstatus = 0;
test.returnBook(asker);
assertEquals(1, test.booksList[2].checkoutstatus);
}
#Test
public void checkoutMovieTest() {
BibliotecaApp test = mock(BibliotecaApp.class);
BibliotecaApp.IntegerAsker asker = mock(BibliotecaApp.IntegerAsker.class);
when(asker.ask("Enter the serial number of the movie that you want to checkout")).thenReturn(2);
test.addMovies();
test.checkoutMovie(asker);
assertEquals(0, test.moviesList[2].checkoutstatus);
}
#Test
public void returnMovieTest() {
BibliotecaApp test = mock(BibliotecaApp.class);
BibliotecaApp.IntegerAsker asker = mock(BibliotecaApp.IntegerAsker.class);
when(asker.ask("Enter the serial number of the movie that you want to return")).thenReturn(2);
test.addMovies();
test.moviesList[2].checkoutstatus = 0;
test.returnMovie(asker);
assertEquals(1, test.moviesList[2].checkoutstatus);
}
// #Test
// public void checkoutWithoutLoginTest(){
// BibliotecaApp test = mock(BibliotecaApp.class);
// BibliotecaApp.IntegerAsker asker = mock(BibliotecaApp.IntegerAsker.class);
// when(asker.ask("Enter your choice. ")).thenReturn(8);
// test.loginStatus = false;
//
//
// test.mainMenuaction(3,asker);
//
// verify(test,times(0)).checkout(asker);
// }
}
If I comment out the last test (that is already commented out) all my tests run successfully! However if I do not comment it out, one test fails but that is not this test! It is the welcometest that fails!

BibliotecaApp test = mock(BibliotecaApp.class);
BibliotecaApp.IntegerAsker asker = mock(BibliotecaApp.IntegerAsker.class);
test.welcome(asker);
verify(asker).printLine("**** Welcome Customer! We are glad to have you at Biblioteca! ****");
Create a MOCK BibliotecaApp
Create a MOCK BibliotecaApp.IntegerAsker
Run the method welcome on the MOCK with a MOCK as a parameter
Expect that your MOCK did call another method.
Question: Why should it do that? You never told it to. Your test object will return null and not call any printLine method.
So, personally, I highly doubt that this test will ever run successfully, in isolation or otherwise. It also doesn't make any sense, since you are testing the behavior of a mock object. But we can assume that Mockito itself is already tested fairly well. You (probably) need to use a real BibliotecaApp instead of a Mock.

Related

Unit test for Spring KafkaListener with "Acknowledge" interface as an argument

I'm not expert at unit test but trying to write unit test for :
#KafkaListener(id = "group_id", topics = "topic" )
public AvroObject listen(AvroObject test, Acknowledgment ack)
But no idea how I can make it when there is and interface as an argument. I try this but not sure is it something useful or not make sense as an test :
#InjectMocks
KafkaConsumer kafkaConsumerTest;
#Test
#DisplayName("Assert Valid Consume")
void consumeValidEvent() throws URISyntaxException, IOException, InterruptedException {
// given
AvroObject event = createEvent(); //Create sample object as AvroObject
// when
AvroObject response = kafkaConsumerTest.listen(event, new Acknowledgment() {
#Override
public void acknowledge() {
}
#Override
public void nack(long sleep) {
//do nothing
}
// then
assertNotNull(response);
assertEquals(response.getCode1() ,98765);
assertEquals(response.getCode2() ,123456);
}
I was wondering if you can give me the best approach for this situation! cheers

How to run different tests on a single Document variable which was fetched with Jsoup.connect(string)

I have multiple test cases and I want to use a single Document variable with all of them.
There are more test units which will use this Document.
I had an idea to download the html code, in order to avoid connecting to the site multiple times and taking up server resources, but still I think that it wouldn't be an optional approach to testing.
public class ScrapperTest {
public ScrapperTest() {
}
#BeforeClass
public static void setUpClass() {
}
#AfterClass
public static void tearDownClass() {
}
#Before
public void setUp() {
}
#After
public void tearDown() {
}
/**
* Test of scrapeManufacturer method, of class Scrapper.
*/
#Test
public void testScrapeManufacturer() {
System.out.println("scrapeManufacturer");
Document html = null;
Scrapper instance = new ScrapperImpl();
String expResult = "";
String result = instance.scrapeManufacturer(html);
assertEquals(expResult, result);
// TODO review the generated test code and remove the default call to fail.
}
/**
* Test of scrapeMinPrice method, of class Scrapper.
*/
#Test
public void testScrapeMinPrice() {
System.out.println("scrapeMinPrice");
Document html = null;
Scrapper instance = new ScrapperImpl();
String expResult = "";
String result = instance.scrapeMinPrice(html);
assertEquals(expResult, result);
// TODO review the generated test code and remove the default call to fail.
fail("The test case is a prototype.");
}

how to unit test block of code that has db call and subsequent line depending on the db call

How to write junit test for testing the block of function that has the db call and the subsequent lines based on the db call result? any samples or example is appreciated
My function to test:
public String functionality(String input)
{
String readDBValue = db.giveMeValue();
if (input.contains(readDBValue))
{
return input;
}
else
{
return null;
}
}
My Junit4 test case:
public class JunitTest
{
#Test
public void testFunctionality()
{
String inputTst = "new input";
String expectTst = "new input";
assertEquals(functionality(input), expectTst);
}
}
How to test the line in functionality that returns some value from database from a dependent function?
Can you mock the DB and inject the mock into whatever class you are testing?
Using a test double of some description for the database will speed up your tests and allow you to specify the behaviour of the database calls so you can test branches in your code.
Edited 2019-04-28 18:17:00+13:00: Adding a code sample to illustrate.
import static org.mockito.Mockito.*;
import static org.junit.Assert.*;
public class TestMyClass {
#Test
public void test1() {
// create mock
MyDatabase mockDb = mock(MyDatabase.class);
// set behaviour required in test
when(mockDb.giveMeValue()).thenReturn("new input");
// inject mock into object being tested
MyClass objectUnderTest = new MyClass(mockDb);
// use mock in test....
assertEquals(objectUnderTest.functionality("input"), "new input");
}
}

How to compare two objects in Junit

I am new to java & Junit. Please help to write Junit test case to test the CargoBO method where Equals & Hashcode functionalities are not implemented.Basically i need to compare 2 objects using Equalbuilder class in junit.
public class CargoBO {
public Cargo cargoDetails(String name,String desc,double length,double width) {
return new Cargo(name,desc,length,width);
}
}
public class CargoJUnit {
Cargo cargo;
#Before
public void createObjectForCargo() {
cargo = new Cargo("audi","des",123.00,234.00);
}
#Test
public void testCargoDetails() {
CargoBO cargoBO = new CargoBO();
//assertTrue(cargo.equals(cargoBO.cargoDetails("audi","des",123.00,234.00)));
Assert.assertEquals(cargo, cargoBO.cargoDetails("audi","des",123.00,234.00));
}
}
Correct test case for your scenario is
#Test
public void testCargoDetails() {
String name = "test name";
String desc = "desc";
double length = 10d;
double width = 100d;
Cargo result = cargoBO.cargoDetails(name, desc, length, width);
Assert.assertEquals(cargo.getName, name);
Assert.assertEquals(cargo.getDesc, desc);
Assert.assertEquals(cargo.getLength, length);
Assert.assertEquals(cargo.getWidth, width);
}
You are testing a method which accepts parameters and calls a constructor passing those parameters.
Your test should be verifying if the given parameters are correctly passed by the method or not.

Apache Camel Integration Test - NotifyBuilder

I am writing integration tests to test existing Routes. The recommended way of getting the response looks something like this (via Camel In Action section 6.4.1):
public class TestGetClaim extends CamelTestSupport {
#Produce(uri = "seda:getClaimListStart")
protected ProducerTemplate producer;
#Test
public void testNormalClient() {
NotifyBuilder notify = new NotifyBuilder(context).whenDone(1).create();
producer.sendBody(new ClientRequestBean("TESTCLIENT", "Y", "A"));
boolean matches = notify.matches(5, TimeUnit.SECONDS);
assertTrue(matches);
BrowsableEndpoint be = context.getEndpoint("seda:getClaimListResponse", BrowsableEndpoint.class);
List<Exchange> list = be.getExchanges();
assertEquals(1, list.size());
System.out.println("***RESPONSE is type "+list.get(0).getIn().getBody().getClass().getName());
}
}
The test runs but I get nothing back. The assertTrue(matches) fails after the 5 second timeout.
If I rewrite the test to look like this I get a response:
#Test
public void testNormalClient() {
producer.sendBody(new ClientRequestBean("TESTCLIENT", "Y", "A"));
Object resp = context.createConsumerTemplate().receiveBody("seda:getClaimListResponse");
System.out.println("***RESPONSE is type "+resp.getClass().getName());
}
The documentation is a little light around this so can anyone tell me what I am doing wrong with the first approach? Is there anything wrong with following the second approach instead?
Thanks.
UPDATE
I have broken this down and it looks like the problem is with the mix of seda as the start endpoint in combination with the use of a recipientList in the Route. I've also changed the construction of the NotifyBuilder (I had the wrong endpoint specified).
If I change the start endpoint to
direct instead of seda then the test will work; or
If I comment out the recipientList
then the test will work.
Here's a stripped down version of my Route that reproduces this issue:
public class TestRouteBuilder extends RouteBuilder {
#Override
public void configure() throws Exception {
// from("direct:start") //works
from("seda:start") //doesn't work
.recipientList(simple("exec:GetClaimList.bat?useStderrOnEmptyStdout=true&args=${body.client}"))
.to("seda:finish");
}
}
Note that if I change the source code of the NotifyTest from the "Camel In Action" source to have a route builder like this then it also fails.
Try to use "seda:getClaimListResponse" in the getEndpoint to be sure the endpoint uri is 100% correct
FWIW: It appears that notifyBuilder in conjunction with seda queues are not quite working: a test class to illustrate:
public class NotifyBuilderTest extends CamelTestSupport {
// Try these out!
// String inputURI = "seda:foo"; // Fails
// String inputURI = "direct:foo"; // Passes
#Test
public void testNotifyBuilder() {
NotifyBuilder b = new NotifyBuilder(context).from(inputURI)
.whenExactlyCompleted(1).create();
assertFalse( b.matches() );
template.sendBody(inputURI, "Test");
assertTrue( b.matches() );
b.reset();
assertFalse( b.matches() );
template.sendBody(inputURI, "Test2");
assertTrue( b.matches() );
}
#Override
protected RouteBuilder createRouteBuilder() throws Exception {
return new RouteBuilder() {
#Override
public void configure() throws Exception {
from(inputURI).to("mock:foo");
}
};
}
}