CDI #Decorator, Is there a way to deactivate a decorator at runtime? - cdi

I use the following workaround in order to control the behaviour of a #Decorator since I couldn't find a way to deactivate it.
if (!FacesContext.getCurrentInstance().getViewRoot().getViewId()
.endsWith("decoratorDemo.xhtml")) {
return transInterBean.getTransactionalInsertRecords();
} else {
...
}
Is there no way to decide at runtime whether a decorator should be applied?
package com.cdi.decorators;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Iterator;
import javax.decorator.Decorator;
import javax.decorator.Delegate;
import javax.enterprise.inject.Any;
import javax.faces.context.FacesContext;
import javax.inject.Inject;
import com.cdi.cdibeans.TransactionalInterceptor;
import com.cdi.cdibeans.TransactionalInterceptorBean;
#Decorator
public abstract class TransactionalInterceptorDecorator implements
TransactionalInterceptor {
/**
*
*/
private static final long serialVersionUID = -1191671082441891759L;
#Inject
#Delegate
#Any
TransactionalInterceptorBean transInterBean;
#Override
public ArrayList<String> getTransactionalInsertRecords()
throws SQLException {
ArrayList<String> records = new ArrayList<String>();
if (!FacesContext.getCurrentInstance().getViewRoot().getViewId()
.endsWith("decoratorDemo.xhtml")) {
return transInterBean.getTransactionalInsertRecords();
} else {
Iterator<String> iter = transInterBean
.getTransactionalInsertRecords().iterator();
while (iter.hasNext()) {
String record = iter.next();
records.add(record);
records.add(">>>Decorator<<< Added record ... ");
}
if (records.isEmpty()) {
records.add(">>>Decorator<<< Currently there are no records yet!");
}
return records;
}
}
}

Deltaspike has an exclude feature ... may be this could help, I didn't try it with decorators.

Related

Quarkus Panache Mockito fails

I struggle with mocking a Panache repository.
Here is the Entity:
import javax.persistence.*;
#Entity
public class Thing {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id", nullable = false)
private Long id;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
}
Simple repository:
import io.quarkus.hibernate.orm.panache.PanacheRepository;
import javax.enterprise.context.ApplicationScoped;
#ApplicationScoped
public class ThingRepository implements PanacheRepository<Thing> {
}
This is the resource:
import javax.inject.Inject;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import java.util.List;
#Path("/things")
#Produces(MediaType.APPLICATION_JSON)
#Consumes(MediaType.APPLICATION_JSON)
public class ThingResource {
#Inject
ThingRepository thingRepository;
#GET
public List<Thing> list() {
return thingRepository.listAll();
}
}
and a simple test where I try to mock the repository:
import io.quarkus.test.junit.QuarkusTest;
import io.quarkus.test.junit.mockito.InjectMock;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import javax.inject.Inject;
import java.util.ArrayList;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertNotNull;
#QuarkusTest
class ThingResourceTest {
private Thing thing;
#Inject ThingResource thingResource;
#InjectMock ThingRepository thingRepository;
#BeforeEach
void setUp() {
Thing thing = new Thing();
thing.setId(1L);
}
#Test
void getAll() {
List<Thing> things = new ArrayList<Thing>();
things.add(thing);
Mockito.when(thingRepository.listAll()).thenReturn(things);
List<Thing> response = thingResource.list();
assertNotNull(response);
assertNotNull(response.get(0));
}
}
The test fails because the response list is <null>.
The debugger tells me the thingRepository is actually mocked. But for some reason Mockito.when().thenReturns() does not return the list I set up.
What am I missing?
Thank you for any help.
I had the thing double declared. One time as class variable, and again in setUp(). Bummer. I apologize for the noise.

My controller code is not reachable from the MockMvc get request and i am always getting 404

I am trying to mock my controller and write testcases for it. But when I tried to debug the Test class the control is not getting into my Controller class. I am not sure what I am doing wrong here.
Please help me to resolve this as I am stuck on this for almost more that 3 hours.
My Service class
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.bnpp.leavemanagement.dao.DepartmentRepository;
import com.bnpp.leavemanagement.model.DepartmentModel;
#Service
public class DepartmentService
{
#Autowired
DepartmentRepository depRepo;
public List<DepartmentModel> listDepartment = new ArrayList<>();
public List<DepartmentModel> getAllDepartments()
{
List<DepartmentModel> allDepartment = depRepo.findAll();
return allDepartment;
}
public DepartmentModel fetchDepartmentById( int id)
{
DepartmentModel depDetail = null;
try
{
depDetail = depRepo.findById(Long.valueOf(id)).get();
}
catch(Exception ex)
{
depDetail = null;
}
return depDetail;
}
public DepartmentModel addDepartment(DepartmentModel depDetail)
{
DepartmentModel depExists = null;
if (listDepartment.size() > 0)
{
depExists = listDepartment.stream()
.filter(d -> d.getName().equalsIgnoreCase(depDetail.getName()))
.findFirst()
.orElse(null);
}
//Below condition is to restrict duplicate department creation
if(depExists == null)
{
depRepo.save(depDetail);
listDepartment.add(depDetail);
}
else
{
return null;
}
return depDetail;
}
public DepartmentModel updateDepartment(DepartmentModel depDetail)
{
DepartmentModel depUpdate = null;
try
{
depUpdate = depRepo.findById(depDetail.getId()).get();
depUpdate.setName(depDetail.getName());
depRepo.save(depUpdate);
}
catch(Exception ex)
{
depUpdate = null;
}
return depUpdate;
}
public DepartmentModel deleteDepartment(DepartmentModel depDetail)
{
try
{
depRepo.deleteById(depDetail.getId());
}
catch(Exception ex)
{
return null;
}
return depDetail;
}
}
My Test Class
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import java.util.ArrayList;
import java.util.List;
import org.hamcrest.Matchers;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.context.annotation.Description;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import org.springframework.web.context.WebApplicationContext;
import com.bnpp.leavemanagement.controller.DepartmentController;
import com.bnpp.leavemanagement.model.DepartmentModel;
import com.bnpp.leavemanagement.service.DepartmentService;
#ExtendWith(MockitoExtension.class)
#WebMvcTest(DepartmentController.class)
#ContextConfiguration(classes = com.bnpp.leavemanagementsystem.LeaveManagementSystemApplicationTests.class)
public class DepartmentControllerTest {
#MockBean
DepartmentService depService;
#Autowired
private MockMvc mockMvc;
#InjectMocks
DepartmentController departmentController;
#Autowired
private WebApplicationContext webApplicationContext;
#Test
#Description("Should return a list of DepartmentModel objects when called")
void shouldReturnListOfDepartmentModel() throws Exception
{
DepartmentModel depModel = new DepartmentModel();
depModel.setId(1L);
depModel.setName("Mock");
List<DepartmentModel> listDepmodel = new ArrayList<>();
listDepmodel.add(depModel);
Mockito.when(depService.getAllDepartments()).thenReturn(listDepmodel);
mockMvc.perform(MockMvcRequestBuilders.get("/department"))
.andDo(print())
.andExpect(status().isOk())
.andExpect(MockMvcResultMatchers.jsonPath("$.size()", Matchers.is(1)))
.andExpect(MockMvcResultMatchers.jsonPath("$[0].id").value(1))
.andExpect(MockMvcResultMatchers.jsonPath("$[0].name").value("Mock"));
}
}
My Controller class
package com.bnpp.leavemanagement.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import com.bnpp.leavemanagement.dao.DepartmentRepository;
import com.bnpp.leavemanagement.model.DepartmentModel;
import com.bnpp.leavemanagement.service.DepartmentService;
#RestController
public class DepartmentController
{
#Autowired
DepartmentService depService;
#GetMapping("/department")
public ResponseEntity<List<DepartmentModel>> getDepartments()
{
List<DepartmentModel> allDepartment = depService.getAllDepartments();
if(allDepartment.size() == 0)
{
return new ResponseEntity( HttpStatus.NOT_FOUND);
}
return new ResponseEntity( allDepartment, HttpStatus.OK);
}
#GetMapping("/department/{id}")
public ResponseEntity<DepartmentModel> fetchDepartmentById(#PathVariable("id") int id)
{
DepartmentModel resDep = depService.fetchDepartmentById(id);
if(resDep == null)
{
return new ResponseEntity(HttpStatus.NOT_FOUND);
}
else
{
return new ResponseEntity( resDep, HttpStatus.OK);
}
}
#PostMapping("/department/create")
public ResponseEntity<DepartmentModel> createDepartment(#RequestBody DepartmentModel depNew)
{
DepartmentModel resDep = depService.addDepartment(depNew);
if(resDep == null)
{
return new ResponseEntity(HttpStatus.EXPECTATION_FAILED);
}
else
{
return new ResponseEntity( resDep, HttpStatus.CREATED);
}
}
#PutMapping("/department/update")
public ResponseEntity<DepartmentModel> updateDepartment(#RequestBody DepartmentModel depNew)
{
DepartmentModel resDep = depService.updateDepartment(depNew);
if(resDep == null)
{
return new ResponseEntity(HttpStatus.NOT_FOUND);
}
else
{
return new ResponseEntity( resDep, HttpStatus.OK);
}
}
#DeleteMapping("/department/delete")
public ResponseEntity<DepartmentModel> deleteDepartment(#RequestBody DepartmentModel depDel)
{
DepartmentModel resDep = depService.deleteDepartment(depDel);
if(resDep == null)
{
return new ResponseEntity(HttpStatus.NOT_FOUND);
}
else
{
return new ResponseEntity(HttpStatus.OK);
}
}
}
The minimal viable test setup to use MockMvc with #WebMvcTest is the following:
#WebMvcTest(DepartmentController.class)
class DepartmentControllerTest {
#MockBean
DepartmentService depService;
#Autowired
private MockMvc mockMvc;
#Test
#Description("Should return a list of DepartmentModel objects when called")
void shouldReturnListOfDepartmentModel() throws Exception {
DepartmentModel depModel = new DepartmentModel();
depModel.setId(1L);
depModel.setName("Mock");
List<DepartmentModel> listDepmodel = new ArrayList<>();
listDepmodel.add(depModel);
Mockito.when(depService.getAllDepartments()).thenReturn(listDepmodel);
mockMvc.perform(MockMvcRequestBuilders.get("/department"))
.andDo(print())
.andExpect(status().isOk())
.andExpect(MockMvcResultMatchers.jsonPath("$.size()", Matchers.is(1)))
.andExpect(MockMvcResultMatchers.jsonPath("$[0].id").value(1))
.andExpect(MockMvcResultMatchers.jsonPath("$[0].name").value("Mock"));
}
}
Explanation:
#InjectMocks is not necessary as with #MockBean you're adding a mocked version of DepartmentService to your Spring TestContext and Spring DI's mechanism will inject it to your DepartmentController
#ExtendWith(SpringExtension.class) is also redundant, as the meta annotation #WebMvcTest already activates the SpringExtension.class
You don't need #ContextConfiguration here as #WebMvcTest takes care to detect your Spring Boot entrypoint class and start a sliced context
If the test still doesn't work, please add all your dependencies, the way you structure your code, and your main Spring Boot class (annotated with #SpringBootApplication).
Further reads that might shed some light on this:
Difference Between #Mock and #MockBean
Guide to Testing Spring Boot Applications With MockMvc

How to test a Controller and Model in a JSF Project with jUnit?

i don't know exactly how to write tests for these following Classes especially for the Controller and Model. Is it to possible to test with jUnit ?
I heard from Selenium but first i would test with jUnit. Thanks for ur help and best regards.
Controller.class:
import factory.InfoMessageFactory;
import entity.Product;
import java.io.Serializable;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.enterprise.context.SessionScoped;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.inject.Inject;
import javax.inject.Named;
import model.ProductModel;
import project.Konstanten;
#Named(value = "ProductController")
#SessionScoped
public class ProductController implements Serializable {
private Product product;
#Inject
private ProductModel model;
#PostConstruct
public void init() {
this.product = new Product();
}
public String addProduct() {
this.model.newProduct(this.product);
}
public Product getProduct() {
return product;
}
public void setProdukt(Product product) {
this.product = product;
}
public List<Product> getProducts() {
return this.model.getProducts();
}
}
Model.class
package model;
import ejb.DB;
import entity.Product;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.enterprise.context.Dependent;
import javax.inject.Inject;
#Dependent
public class ProductModel implements Serializable{
#Inject
private DB db;
public boolean addProduct(Product p){
try{
db.persist(p);
}catch(Exception e){
System.out.println("Blablabla");
return false;
}
return true;
}
}
And DB.class
#Stateless
public class DB {
#Inject
#RealClass
private EntityManager em;
public void persist(Object object) {
em.persist(object);
}
In the ProductController, there is really not much to test.. unless there is more logic that you did not post.
For testing the ProductModel, or any service-like class having the DB dependency i would suggest adding a project dependency to one of the mocking frameworks (i suggest Mockito as it is the most mature of them all).
For the addProducts method you could end up with following tests:
import static org.mockito.Mockito.*;
import org.junit.Test;
import org.mockito.MockitoAnnotations;
public class ProductModelTest{
#Mock
private DB dbMock;
#InjectMocks
private ProdcutModel = new ProductModel();
#Before
public void init(){
MockitoAnnotations.iniMocks(this);
}
#Test
public void shouldReturnTrue_whenEntityPersisted(){
doNothing().when(dbMock).persist(any(Product.class));
boolean result = productModel.addProduct(new Product());
assertTrue(result);
}
#Test
public void shouldReturnFalse_whenEntityPersisted(){
doThrow(RuntimeException.class).when(dbMock).persist(any(Product.class));
boolean result = productModel.addProduct(new Product());
assertFalse(result);
}
}
Regarding the DB-like repository classes.. i normally do not unit-test them. IF so i run integration tests on them.

How do I use Mockito to test that a Java 8 Stream had the expected values?

One of the interactions I want to test is that a class Foo is supposed to pass a Stream<Changes> to FooListener.someChangesHappened. Is there a Mockito idiom to verify that a stream contained the expected objects?
Assuming you are just verifying the argument to a mock implementation, and are not actually using it, here is a custom Hamcrest Matcher that will get the job done. It gets hairy when you need to read from the Stream more than once, because Streams are not built for that. You'll notice that this solution even needs to protect itself from JUnit calling matches more than once.
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeMatcher;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static org.hamcrest.Matchers.hasItem;
import static org.hamcrest.Matchers.not;
import static org.mockito.Matchers.argThat;
import static org.mockito.Mockito.verify;
#RunWith(MockitoJUnitRunner.class)
public class Foo {
#Mock
FooListener fooListener;
#Before
public void happen() {
fooListener.someChangesHappened(Stream.of(Changes.ONE, Changes.TWO, Changes.THREE));
}
#Test
public void contains() {
verify(fooListener).someChangesHappened(argThat(streamThat(hasItem(Changes.TWO))));
}
#Test
public void doesNotContain() {
verify(fooListener).someChangesHappened(argThat(streamThat(not(hasItem(Changes.FOUR)))));
}
private static <T> Matcher<Stream<T>> streamThat(Matcher<Iterable<? super T>> toMatch) {
return new IterableStream<>(toMatch);
}
private interface FooListener {
void someChangesHappened(Stream<Changes> stream);
}
private enum Changes {
ONE, TWO, THREE, FOUR
}
private static class IterableStream<T> extends TypeSafeMatcher<Stream<T>> {
Matcher<Iterable<? super T>> toMatch;
List<T> input = null;
public IterableStream(Matcher<Iterable<? super T>> toMatch) {
this.toMatch = toMatch;
}
#Override
protected synchronized boolean matchesSafely(Stream<T> item) {
// This is to protect against JUnit calling this more than once
input = input == null ? item.collect(Collectors.toList()) : input;
return toMatch.matches(input);
}
#Override
public void describeTo(Description description) {
description.appendText("stream that represents ");
toMatch.describeTo(description);
}
}
}

JSF - Getting NullPointerException in constructor when accessing getFacade()

this code produces NullPointerException. I don't know why. When I put the code from constructor to some other void with #PostConstruct - it works. I tried to initiate klientFacade - but it's not working, either. The class KlientFacade is #Stateless.
package view;
import entity.Klient;
import facade.KlientFacade;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import static util.Messages.addFlashMessage;
#ManagedBean
#ViewScoped
public class ManageClient implements Serializable {
#EJB
private KlientFacade klientFacade;
private List<Klient> clientList;
public List<Klient> returnClientList(){
return getKlientFacade().findAll();
}
public ManageClient() {
clientList = new ArrayList<>();
clientList = returnClientList();
}
public String removeClient(Klient klient){
addFlashMessage("Klient ["+klient.getLogin()+"] został usunięty.");
getKlientFacade().remove(klient);
return "manage";
}
public List<Klient> getClientList() {
return clientList;
}
public void setClientList(List<Klient> clientList) {
this.clientList = clientList;
}
public KlientFacade getKlientFacade() {
return klientFacade;
}
public void setKlientFacade(KlientFacade klientFacade) {
this.klientFacade = klientFacade;
}
}
Well its because injected objects are not instantiated before the constructor call. Thats why you are not getting NPE with #PostConstruct annotation. If you still need to access injected fields in constructor, try http://openejb.apache.org/constructor-injection.html.

Resources