Java/JUnit - How does testPrintMessage() get called? - junit

In the following code, how does method testPrintMessage() get called? I dont see any code explicitly calling it.
TestRunner.java
import org.junit.runner.JUnitCore;
import org.junit.runner.Result;
import org.junit.runner.notification.Failure;
public class TestRunner {
public static void main(String[] args) {
Result result = JUnitCore.runClasses(TestJunit.class);
for (Failure failure : result.getFailures()) {
System.out.println(failure.toString());
}
System.out.println(result.wasSuccessful());
}
}
TestJunit.java
import org.junit.Test;
import static org.junit.Assert.assertEquals;
public class TestJunit {
String message = "Hello World";
MessageUtil messageUtil = new MessageUtil(message);
#Test
public void testPrintMessage() {
assertEquals(message,messageUtil.printMessage());
}
}
MessageUtil.java
public class MessageUtil {
private String message;
//Constructor
//#param message to be printed
public MessageUtil(String message){
this.message = message;
}
// prints the message
public String printMessage(){
System.out.println(message);
return message;
}
}
I tested this code in Eclipse and it works:
Hello World
true

When JUnitCore.runClasses(TestJunit.class) gets called, JUnit finds all public methods annotated with #Test and invokes them reflectively.

Related

FasterXML ObjectMapper is not working with ExecutorService in a Junit test

It is a very strange issue. Removing the JSON in TestUtil or the executorService/submit will make the following code working:
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInfo;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ATest {
#BeforeAll
public static void setup(TestInfo test) throws Exception {
}
#Test
void testThis(){
int numThreads = 1;
ExecutorService threadPool = Executors.newFixedThreadPool(numThreads);
threadPool.submit(() -> {
TestUtils.doSomething();
});
}
}
Here is the class with the ObjectMapper>
import com.fasterxml.jackson.databind.ObjectMapper;
public class TestUtils {
private static final ObjectMapper JSON;
static {
JSON = new ObjectMapper();
}
public static void doSomething() {
System.out.println("entered the method");
}
}
Currently, the method doSomething() would not be entered at all.
This issue will be resoved if we trigger the Junit test from Maven or if run it from a static main method.

PowerMock ExpectNew creating real objects instead of mocked Ones

public class PersistenceManager {
public boolean addUser(User user) {
UserPersistor userPersistor = new UserPersistor(user) {
#Override
void somemethod() {
// TODO Auto-generated method stub
}
};
userPersistor.addUser();
System.out.println("PersistenceManager added user ");
return true;
}
class User {
public String firstName;
public String lastName;
public User(String firstName, String lastName) {
super();
this.firstName = firstName;
this.lastName = lastName;
}
}
abstract class UserPersistor {
public UserPersistor( ) {
}
public UserPersistor(User user) {
}
public void addUser() {
System.err.println("UserPersistor added user ");
}
abstract void somemethod();
}
}
import static org.powermock.api.easymock.PowerMock.createMock;
import static org.powermock.api.easymock.PowerMock.expectNew;
import static org.powermock.api.easymock.PowerMock.expectLastCall;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.easymock.PowerMock;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
#RunWith(PowerMockRunner.class)
#PrepareForTest( PersistenceManager.class )
public class PersistenceManagerTest {
private User user = null;
#Before
public void before() throws Exception {
user = createMock(User.class);
UserPersistor userPersistor = createMock(UserPersistor.class);
userPersistor.addUser();
expectLastCall();
expectNew(UserPersistor.class, user).andReturn(userPersistor);
PowerMock.replayAll();
}
#Test
public void testaddUser() {
PersistenceManager tested = new PersistenceManager();
tested.addUser(user);
PowerMock.verifyAll();
}
}
Whats wrong with above code? I dont see mocked object for UserPersistor. Meaning, i dont want to see "UserPersistor added user " printed. It should not do anything. But it is printing it since real object of UserPersistor is created. I am facing this problem in my actual project, thought would simulate and try to solve in a much smaller context. But I am stumped.
That's because you are not expecting to instantiate UserPersistor but an anonymous inner class extending UserPersistor.
To do that you need to retrieve that class, mock it and expect it. PowerMock has a Whitebox class to do that. You are exposing the class implementation when using it. I would recommend that you refactor your code to inject the code instead. But if you really want to, you should write this:
#Before
public void before() throws Exception {
user = createMock(PersistenceManager.User.class);
Class<Object> clazz = Whitebox.getAnonymousInnerClassType(PersistenceManager.class, 1);
PersistenceManager.UserPersistor userPersistor = createMock(clazz);
userPersistor.addUser();
expectNew(clazz, user).andReturn(userPersistor);
PowerMock.replayAll();
}

How can I read a JSON with header and body with spring boot

Good morning I have a small query, I am doing a small web service rest with spring boot, the issue is that it is working fine and everything else, as I am doing as follows, receives a parameter and returns a response based on a Stored Procedue in the database:
But now I have changed the request, and it is including header and body, like the following:
{
"ValidateClient": {
"Header": {
"country": "VE",
"lang": "ES",
"entity": "TMVE",
"system": "76",
"subsystem": "APP",
"operation": "ValidateClient",
"timestamp": "2019-10-23T08:48:08.474Z",
"msgType": "REQUEST"
},
"Body": {
"validateClientRequest": {
"movil": "04141734272"
}
}
}
}
Which when executing it gives me an answer of not found the mobile, it is a default response when it cannot read the mobile parameter or it is sent empty
My Code
Main Class
package com.app.validate;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class ValidateClientApp {
public static void main(String[] args) {
SpringApplication.run(ValidateClientApp.class, args);
}
}
Controller
package com.app.validate.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import com.app.validate.dao.ValidateClientAppRepository;
import com.app.validate.entity.DriverBonificados;
import com.app.validate.entity.ResponseVo;
#RestController
public class ValidateClientAppController {
#Autowired
private ValidateClientAppRepository dao;
#PostMapping(value = "/ValidateClientApp",consumes = "application/json",produces="application/json")
public ResponseVo ValidateClient(#RequestBody DriverBonificados driver) {
//System.out.println(driver.getMovil());
return dao.validarClienteBonifiado(driver.getMovil());
}
}
Dao
package com.app.validate.dao;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import com.app.validate.entity.DriverBonificados;
import com.app.validate.entity.ResponseVo;
#Repository
public interface ValidateClientAppRepository extends JpaRepository<DriverBonificados, Integer> {
#Query(nativeQuery = true,value = "call ValidacionClienteBonificado(:movil)")
ResponseVo validarClienteBonifiado(#Param("movil") String pMovil);
}
Entity
package com.app.validate.entity;
import java.util.Date;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
#Table(name="DriverBonificados")
public class DriverBonificados {
#Id
private int id;
private String movil;
private String contador;
private Date fecha_driver;
private Date fecha_alta;
private Date fecha_fin;
private Date codigo_transaccion;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getMovil() {
return movil;
}
public void setMovil(String movil) {
this.movil = movil;
}
public String getContador() {
return contador;
}
public void setContador(String contador) {
this.contador = contador;
}
public Date getFecha_driver() {
return fecha_driver;
}
public void setFecha_driver(Date fecha_driver) {
this.fecha_driver = fecha_driver;
}
public Date getFecha_alta() {
return fecha_alta;
}
public void setFecha_alta(Date fecha_alta) {
this.fecha_alta = fecha_alta;
}
public Date getFecha_fin() {
return fecha_fin;
}
public void setFecha_fin(Date fecha_fin) {
this.fecha_fin = fecha_fin;
}
public Date getCodigo_transaccion() {
return codigo_transaccion;
}
public void setCodigo_transaccion(Date codigo_transaccion) {
this.codigo_transaccion = codigo_transaccion;
}
}
Interface Response Stored Procedue
package com.app.validate.entity;
public interface ResponseVo {
String getCode();
String getResult();
}
How could you do to read the Json with header and body? I'm new to spring boot
UPDATE
According to what Silverfang said, I created the classes said by him, but I get an error that I describe next:
BodyRequest.java
public class BodyRequest {
private String validateClientRequest;
private String movil;
public String getValidateClientRequest() {
return validateClientRequest;
}
public void setValidateClientRequest(String validateClientRequest) {
this.validateClientRequest = validateClientRequest;
}
public String getMovil() {
return movil;
}
public void setMovil(String movil) {
this.movil = movil;
}
}
HeaderRequest.java
package com.app.validate.controller;
import java.util.Date;
public class HeaderRequest {
private String country;
private String lang;
private String entity;
private String system;
private String subsystem;
private String operation;
private Date timestamp;
private String msgType;
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public String getLang() {
return lang;
}
public void setLang(String lang) {
this.lang = lang;
}
public String getEntity() {
return entity;
}
public void setEntity(String entity) {
this.entity = entity;
}
public String getSystem() {
return system;
}
public void setSystem(String system) {
this.system = system;
}
public String getSubsystem() {
return subsystem;
}
public void setSubsystem(String subsystem) {
this.subsystem = subsystem;
}
public String getOperation() {
return operation;
}
public void setOperation(String operation) {
this.operation = operation;
}
public Date getTimestamp() {
return timestamp;
}
public void setTimestamp(Date timestamp) {
this.timestamp = timestamp;
}
public String getMsgType() {
return msgType;
}
public void setMsgType(String msgType) {
this.msgType = msgType;
}
}
RequestBodyDemo.java
package com.app.validate.controller;
public class RequestBodyDemo {
private ValidateClientRequest ValidateClient;
public ValidateClientRequest getValidateClient() {
return ValidateClient;
}
public void setValidateClient(ValidateClientRequest validateClient) {
ValidateClient = validateClient;
}
}
ValidateClientRequest
package com.app.validate.controller;
public class ValidateClientRequest {
private BodyRequest Body;
private HeaderRequest Header;
public BodyRequest getBody() {
return Body;
}
public void setBody(BodyRequest body) {
Body = body;
}
public HeaderRequest getHeader() {
return Header;
}
public void setHeader(HeaderRequest header) {
Header = header;
}
}
My Controller (Update)
package com.app.validate.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import com.app.validate.dao.ValidateClientAppRepository;
import com.app.validate.entity.DriverBonificados;
import com.app.validate.entity.ResponseVo;
#RestController
public class ValidateClientAppController {
#Autowired
private ValidateClientAppRepository dao;
#PostMapping(value = "/ValidateClientApp",consumes = "application/json",produces="application/json")
public ResponseVo ValidateClient(#RequestBody RequestBodyDemo req) {
System.out.println(req.getValidateClient().getBody().getMovil());
return dao.validarClienteBonifiado(req.getValidateClient().getBody().getMovil());
}
}
The error I get:
From what I understand you have changed the request format and now want the same request body to work for the same controller.
I think you were trying to add the fields to the header. What you are doing here is not the right way to do it. It should goes to header section rather than in the body section of the Postman app. But doing so, you will have to specify these header separately as these are custom headers which will be a lot of work.
Answer to your question
Going by what you were trying to do. Since now you have changed the request body. You will have to make changes in the controller class too. Now it will require three classes If you want to do it in a modular way.
The first class will be BodyRequest.java
private string validateClientRequest;
private string movil;
The next class will be HeaderRequest.java
private string country;
private string lang;
private string entity;
private string system;
private string subsystem;
private string operation;
private Date timestamp;
private string msgType;
Next class will be ValidateClientRequest.java
private HeaderRequest Header;
private BodyRequest Body;
Now for the RequestBodyDemo class;
private ValidateClientRequest ValidateClient;
Note : Use appropriate Getter and setter along with #JsonProperty if you are masking the input request data.
Once these things are done. In your controller Instead of using Entity in #RequestBody Use the class RequestBodyDemo. Once that is done. Just try printing the values just to check whether you are getting them right or not. Then use getter for fetching any value that you need.
Edit :
public ResponseVo ValidateClient(#RequestBody RequestBodyDemo req) {
System.out.println(req.getValidateClient().getBodyrequest().getMovil());
return dao.validarClienteBonifiado(req.getValidateClient().getBodyrequest().getMovil());
}
Note : Use appropriate getter method here.

I am not able to handle the Exception using JAX-RS

This the NullPointerExceptionMapper class
package com.sample.Exceptionhandler;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import javax.ws.rs.ext.ExceptionMapper;
import javax.ws.rs.ext.Provider;
import response.Message;
#Provider
public class NullPointerExceptionMapper implements ExceptionMapper<NullPointerException> {
public Response toResponse(NullPointerException ex) {
Message message=new Message(500,ex.getMessage(),200);
return Response.status(Status.NOT_FOUND).entity(message)
.build();
}
}
This is the Message class
package response;
public class Message {
private int status;
private String message;
private int code;
public Message() {
}
public Message(int status, String message, int code) {
super();
this.status = status;
this.message = message;
this.code = code;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
This is the Controller method
#RequestMapping(value = "/getOrder", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public List<PurchaseOrderHeaderDto> getOrders(){
String exceptionOccured="NULL_POINTER";
if(exceptionOccured.equalsIgnoreCase("NULL_POINTER")){
throw new NullPointerException("Null Pointer Exception");
}
return purchaseImpl.GetPurchaseOrder();
}
I am not able to handle the Exception thrown and I am using JAX-RS for handling it, but it is not working properly any suggestions are welcomed that would help me sort this out.
You're mixing JAX-RS with Spring MVC. Your controller code is Spring MVC and your attempt at exception handling with the ExceptionMapper is JAX-RS. These are two completely different and incompatible frameworks. For Spring MVC, you want to use a #ControllerAdvice class.

Before Class Method of JUnit not called in correct order

I'm new to JUnit and was learning the various annotations. The code below however is giving me output that seems wrong
import static org.junit.Assert.*;
import org.junit.Before;
import org.junit.After;
import org.junit.BeforeClass;
import org.junit.AfterClass;
import org.junit.Test;
public class SampleTest {
#BeforeClass
public static void beforeClass() {
System.out.println("Before Class"); }
#AfterClass
public static void afterClass() {
System.out.println("After Class"); }
#Before
public void before() {
System.out.println("Before"); }
#After
public void after() {
System.out.println("After"); }
#Test
public void testAreFirstAndLastNCharactersTheSame() {
System.out.println("testAreFirstAndLastNCharactersTheSame");}
#Test
public void testTruncateAinFirstNPositions() {
System.out.println("testTruncateAinFirstNPositions"); }
}
The output I get is
Before
testTruncateAinFirstNPositions
After
Before
testAreFirstAndLastNCharactersTheSame
After
Before Class
After Class
This seems wrong as the "Before Class" print should be first. Am I doing something wrong? My Junit version is 4.12. I ran the above piece of code on Intellij.
The actual output screenshot is below