PriorityQueue not printing the things i want - java

Hi this is a test class I have put together before I proceed to my assignment, and I realize it is not working the way I want. Here is my class:
JobLog:
import java.util.PriorityQueue;
public class JobLog {
private PriorityQueue<Job> log;
public JobLog() {
log = new PriorityQueue<Job>();
}
public void addJob(Job newJob) {
log.add(newJob);
}
public void addJob(int clock, int exectionTime, int jobNumber,
int priorityLevel) {
Job newJob = new Job(clock, exectionTime, jobNumber, priorityLevel);
addJob(newJob);
}
public Job getNextJob() {
return log.peek();
}
public Job removeNextJob() {
return log.remove();
}
}
TestClass
public static void main(String[] args) {
// TODO code application logic here
JobLog waitline=new JobLog();
Job Joba=new Job(3,3,4,12);
Job Jobb=new Job(3,3,4,2);
Job Jobc=new Job(3,3,4,3);
Job Jobd=new Job(3,3,4,4);
Job Jobe=new Job(3,3,4,5);
Job Jobf=new Job(3,3,4,5);
Job Jobg=new Job(3,3,4,1);
waitline.addJob(Joba);
waitline.addJob(Jobb);
System.out.println(waitline.getNextJob());
}
I'm getting this result.
assignment3_csc225.Job#1db04ed
I want to return all the information of the job . How?

you have to write a toString method for the job class so that java knows how to display it. What it appears you are getting is the default (Object) toString output.

You can overload the toString() method on the Job class to return the string describing a Job.
Now when you print out a Job, this string will be returned.

Related

Junit Test Bool Value

Hello Every One I Have This Method Which it Checks if the Input String Is Numbers only And Its Return True Or False
I Want To Make A Junit Test For this method and Actually I Don't know how to test Method Like This Can Any One Help And Thank You All.
My Method:
private Boolean Check_Ean(String EAN_Ch)
{
Long EAN;
try
{
EAN = Long.parseLong(EAN_Ch);
return true;
}
catch (NumberFormatException e)
{
return false;
}
}
First you need to create a class in the test folder(located at the same path as main). Then you need to use their annotations to or either Prepare the information, Test and Destroy the information(usefull when you have DB connection opens or streams):
public class TestClass {
#Before
public void setup() {
//prepare information
}
#Test
public void testCheck_Ean() {
boolean result = Check_Ean(...);
Assert.assertTrue(result);
}
#After
public void destroy() {
//if you need to "destroy" some info
}
}
tester = new CLASS_NAME();
assertTrue(tester.Check_Ean("5");
assertFalse(tester.Check_Ean("this is noot a Long");
You might be overthinking it. Also the Check_Ean method maybe could be static if you pass the Ean as a parameter rather than getting a class variable.

Spring batch return custom process exit code

I have one jar with several jobs, I want to execute only one job each time and retrieve a custom exit code.
For example, I have basic job (retrieveErrorsJob) configuration with one step that will read an input XML file and write the data in specific database table.
Application class
#SpringBootApplication
#EnableBatchProcessing
#Import(CoreCommonsAppComponent.class)
public class Application {
private static final Logger logger = LoggerFactory.getLogger(Application.class);
private ConfigurationConstants constants;
#Autowired
public Application(ConfigurationConstants constants) {
this.constants = constants;
}
#EventListener(ApplicationStartedEvent.class)
public void idApplication()
{
logger.info("================================================");
logger.info(constants.APPLICATION_NAME() + "-v." + constants.APPLICATION_VERSION() + " started on " + constants.REMOTE_HOST());
logger.info("------------------------------------------------");
}
public static void main(String... args) throws Exception{
ApplicationContext context = SpringApplication.run(Application.class, args);
logger.info("================================================");
SpringApplication.exit(context);
}
}
I can choose one job from command line:
java -jar my-jar.jar --spring.batch.job.names=retrieveErrorsJob --input.xml.file=myfile.xml
Spring Batch starts the correct job.
The problem is that I need the jar to return a custom process exit integer like ExitCode.FAILED == 4 etc. But I always have a ZERO (if ExitCode = SUCCESS or FAILED).
As per the docs, I need to implement ExitCodeMapper interface.
Code (not finished)
public class CustomExitCodeMapper implements ExitCodeMapper {
private static final int NORMAL_END_EXECUTION = 1;
private static final int NORMAL_END_WARNING = 2;
private static final int ABNORMAL_END_WARNING = 3;
private static final int ABNORMAL_END_ERROR = 4;
#Override
public int intValue(String exitCode) {
System.out.println("EXIT CODE = " + exitCode);
switch (exitCode)
{
case "FAILED":
return ABNORMAL_END_WARNING;
default:
return NORMAL_END_EXECUTION;
}
}
}
I can't find a way to use this custom implementation. I could set the custom implementation to CommandLineJobRunner but how to use this class?
Thanks to #Mahendra I've got an idea :)
I've created a JobCompletionNotificationListener class as #Mahendra suggested:
#Component
public class JobCompletionNotificationListener extends JobExecutionListenerSupport {
private static final Logger logger = LoggerFactory.getLogger(JobCompletionNotificationListener.class);
#Override
public void afterJob(JobExecution jobExecution) {
SingletonExitCode exitCode = SingletonExitCode.getInstance();
if(jobExecution.getStatus() == BatchStatus.COMPLETED)
{
logger.info("Exit with code " + ExitCode.NORMAL_END_OF_EXECUTION);
exitCode.setExitCode(ExitCode.NORMAL_END_OF_EXECUTION);
}
else {
logger.info("Exit with code " + ExitCode.ABNORMAL_END_OF_EXECUTION_WARNING);
exitCode.setExitCode(ExitCode.ABNORMAL_END_OF_EXECUTION_WARNING);
}
}
}
But I don't force the application to exit with System.exit() from this class. I've implemented a simple singleton like this:
public class SingletonExitCode {
public ExitCode exitCode = ExitCode.ABNORMAL_END_OF_EXECUTION_WARNING; // Default code 3
private static SingletonExitCode instance = new SingletonExitCode();
private SingletonExitCode() {}
public static SingletonExitCode getInstance() {
return instance;
}
public void setExitCode(ExitCode exitCode) {
this.exitCode = exitCode;
}
}
and I ask the ExitCode from my singleton after closing Spring context:
#SpringBootApplication
#EnableBatchProcessing
#Import(CoreCommonsAppComponent.class)
public class Application {
// a lot of nice things
public static void main(String... args) throws Exception{
ApplicationContext context = SpringApplication.run(Application.class, args);
logger.info("================================================");
SpringApplication.exit(context);
System.exit(SingletonExitCode.getInstance().exitCode.getCode());
}
}
I did this because if we exit directly from JobCompletionNotificationListener class we miss an important line in the logs:
Job: [FlowJob: [name=writeErrorFromFile]] completed with the following parameters: [{-input.xml.file=c:/temp/unit-test-error.xml, -spring.batch.job.names=writeErrorFromFile, run.id=15, input.xml.file=c:/temp/unit-test-error.xml}] and the following status: [FAILED]
And seems that Spring context is not properly closed.
Despite of exit-status of Sprint-Batch's Job (i.e. COMPLETED or FAILED), java process will be completed successfully (and you will get process exit-code as 0).
If you want a custom exit-code for java process so that you can use it any script or somewhere else, you can use JobExecutionListener.
You can check the job's exitStatus in afterJob() and accordingly exit the java process with your desired exit-code (i.e. 4 for FAILURE)
Example of JobExecutionListener
public class InterceptingExitStatus implements JobExecutionListener{
#Override
public void beforeJob(JobExecution jobExecution) {
}
#Override
public void afterJob(JobExecution jobExecution) {
ExitStatus exitStatus = jobExecution.getExitStatus() ;
if(exitStatus == ExitStatus.COMPLETED ){
System.exit(0);
}
if(exitStatus == ExitStatus.FAILED ){
System.exit(4);
}
}
}
and this is how you can configure job-listener in the xml file -
<job id="job">
....
....
<listeners>
<listener ref="interceptingExitStatus "/>
</listeners>
</job>
Spring Boot and Sring Batch already have an internal solution for this, all you need is an extra line of code:
System.exit(SpringApplication.exit(applicationContext));
Here is another example:
public class BatchApplication {
public static void main(String[] args) {
ApplicationContext applicationContext = SpringApplication.run(BatchApplication.class, args);
System.exit(SpringApplication.exit(applicationContext));
}
}
EDIT: If you would like to know how it works check this class: org.springframework.boot.autoconfigure.batch.JobExecutionExitCodeGenerator

Mockito: Spying calls within the constructor (Java) [duplicate]

This question already has answers here:
Test class with a new() call in it with Mockito
(7 answers)
Closed 5 years ago.
This is not a duplicate of Test class with a new() call in it with Mockito. I'm trying to write a test to verify that certain methods are being called within the constructor of my spy object (mockToyFacade).
The class under test is ToyFactoryFacade. The idea is clients interact with the ToyFactoryFacade (which wraps a ToyFactory) to generate ToyFacades, which itself is a wrapper around the Toy object.
What I am trying to verify with Mockito?
I want to verify that addToyName(toyName) and addCreationTime(creationTimestamp) are being called on the ToyFacade. Both of these methods are called in the constructor of the ToyFacade.
What's the issue?
When I try to spy the ToyFacade, and verify that both aforementioned methods are called, I receive an error, which says "Actually, there were zero interactions with this mock." When I call the methods separately (i.e., not via the constructor), the verification check out correctly. I'm not sure what I'm doing incorrectly.
Test Code
public class ToyFactoryFacadeTest {
private Toy mockToy;
private ToyFacade mockToyFacade;
// System under test.
private ToyFactoryFacade toyFactoryFacade;
private ToyFactory mockToyFactory;
#Before
public void setup() {
mockToy = mock(Toy.class);
mockToyFacade = spy(new ToyFacade(mockToy, "Phone", System.currentTimeMillis()));
mockToyFactory = mock(ToyFactory.class);
toyFactoryFacade = new ToyFactoryFacade(mockToyFactory) {
#Override
public Toy getToyFacade(String toyName, long creationTimestamp){
return mockToyFacade;
}
};
}
#Test
public void testToyFactoryFacade() {
toyFactoryFacade.initializeAndGetToy("Phone", System.currentTimeMillis());
verify(mockToyFacade).addToyName("Phone");
verify(mockToyFacade).addCreationTime(anyLong());
}
}
Source Code
public class ToyFactoryFacade {
private final ToyFactory toyFactory;
public ToyFactoryFacade(ToyFactory toyFactory) {
this.toyFactory = toyFactory;
}
public ToyFacade initializeAndGetToy(String toyName, long creationTimestamp)
{
getToyFacade(toyName, creationTimestamp);
}
// For testing.
protected ToyFacade getToyFacade(String toyName, long creationTimestamp
{
return new ToyFacade(toyFactory.newToy(), toyName, creationTimestamp);
}
}
public class ToyFactory {
public Toy newToy() {
return new Toy();
}
}
public class ToyFacade {
private final Toy toy;
public ToyFacade(Toy toy, String toyName, long creationTimeStamp) {
this.toy = toy;
addToyName(toyName);
addCreationTime(creationTimestamp);
}
public void addToyName(String name) {
toy.addToyName(toyName);
}
public void addCreationTime(long timestamp) {
toy.addCreationTime(timestamp);
}
}
public class Toy {
public String toyName;
public String creationTimestamp;
public void addToyName(String name) {
toyName = name;
}
public void addCreationTime(long timestamp) {
creationTimestamp = timestamp;
}
}
Your test isn't doing what you expect because the method calls that you're trying to verify have already taken place before you create your spy. What you really want to do is to test the effect of those two method calls, rather than the calls themselves. This would look something like
verify(mockToy).addToyName("Phone");
verify(mockToy).addCreationTime(timestamp);
where timestamp is whatever you pass in in the setUp method.

Testing class that insert, update and delete from the db

I have class that has 3 methods: insert, update and delete from the db.
In order to test it in the insert test method I need to use the insert method and after I insert i need to delete what I inserted, but in order to delete I should use the delete method that I also want to test so it didn't make sense to me that I need to use them and also test them.
I hope you understand my problem. Thanks in advance!
You must decide what you want to test. That was you describe, it is an integration test. By a “real” unitTest, you test only your method, and not the System method and not the database.
If you want a unitTest, you have several options. For Example, you work with interfaces and catch your statement before it comes to the database.
Edit 1 - one possibility to implement unit test with interfaces:
You need one interface that implements the method these go to the backend system:
public interface IDatabase{
public returnValue insert(yourParam);
public int update(yourParam);
}
Then you implement your method with the real functions in a class:
public class Database implements IDatabase {
#Override
public returnValue insert(yourParam) {
// do something
return null;
}
#Override
public int update(yourParam){
// do something
return 0;
}
}
This class you call in the main class:
/**
* The real class to do what you want to do.
*/
public class RealClass {
private IDatabase dbInstance = null;
private IDatabase getDbInstance() {
if (dbInstance == null) {
dbInstance = new Database();
}
return dbInstance;
}
protected void setDbInstance(IDatabase dataBase) {
dbInstance = dataBase;
}
public static void main(String[] args) {
getDbInstance().insert(yourParam);
}
}
For the unit test you implement the interface again:
public class UnitTest implements IDatabase {
#Override
public returnValue insert(yourParam) {
// Here can you test your statement and manipulate the return value
return null;
}
#Override
public int update(yourParam){
if (yourParam.containsValue(value1)) {
assertEquals("yourStatement", yourParam);
return 1;
}else if (yourParam.containsValue(value2)) {
assertEquals("yourStatement2", yourParam);
return 5;
}else{
assertTrue(false,"unknown Statement")
}
}
#Test
public void yourTest(){
RealClass.setDbInstance(this);
//Test something
}
}
This is time-consuming to implement, but with this, you are independent from the backend system and you can call the unittest every time without a database.
By default, the order of test methods is not warrantied in JUnit. Nevertheless, as of JUnit 4.11, you can order by the test name, as follows:
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runners.MethodSorters;
#FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class Test1 {
#Test
public void aInsert() {
System.out.println("first INSERT");
}
#Test
public void bUpdate() throws Exception {
System.out.println("second UPDATE");
}
#Test
public void cDelete() throws Exception {
System.out.println("third DELETE");
}
}

Spring AOP: How to pass argument from called method to advice method?

I am designing a system where I need to pass argument from the called method to the advice method. I am providing a simple code to make the point clear -
//AOPMain.java:
public class AOPMain {
public static void main(String[] args) {
ApplicationContext cxt = new ClassPathXmlApplicationContext("spring.xml");
Employee emp = cxt.getBean("employee", Employee.class);
emp.sayHello();
}
}
//Employee.java:
public class Employee {
private String name;
public String getName() {
System.out.println("getName");
return name;
}
public void setName(String name) {
System.out.println("setName");
this.name = name;
}
public void sayHello() {
System.out.println("Hello World!");
//How to pass argument to afterAdvice
}
}
//Logging.java:
#Aspect
public class Logging {
#Pointcut("execution(public void sayHello())")
public void doSomething(){}
#After("doSomething()")
public void afterAdvice() {
System.out.println("After Advice");
//Depending on the argument passed, send notification
}
}
How I can design this system? I know that there are ways to pass the argument to advice method from AOPMain itself using &&args(), but I am not able to find any sample code for this specific problem.
I know it's violating the basic design principle, that the advice method is not loosely coupled. So does Spring support this?
Thanks in advance.
There are two ways to get information from the advised method:
let it return a value and used that returned value in the advice:
public Arg sayHello() {
System.out.println("Hello World!");
//How to pass argument to afterAdvice
Arg arg = ...;
return arg;
}
#AfterReturning(pointcut="doSomething()", returning="retval")
public void afterAdvice(Object retval) {
System.out.println("After Advice");
// use retval here ...
}
use a JoinPoint to get access to the original object on which method was called, and pass arg as an object attribute:
public void sayHello() {
System.out.println("Hello World!");
//How to pass argument to afterAdvice
this.arg = ...;
}
#After("doSomething()")
public void afterAdvice(JoinPoint jp) {
System.out.println("After Advice");
Employee emp = (Employee) jp.getTarget();
// use emp.arg here ...
}
This one only makes sense if the advised object is statefull - do not considere to use it on a service or controller that are shared objects...
#After("doSomething()")
public void afterAdvice(JoinPoint joinPoint) {
System.out.println("After Advice");
//joinPoint.getArgs();
//Depending on the argument passed, send notification
}
Doesn't solve your problem? Refer get-method-arguments-using-spring-aop to know more.

Categories

Resources