Junit testing for exportcsv in spring boot - java

Hi I am new to spring and have created an Export csv application with two controllers which can give all the data as well as selective columns data and want to write junits for the same but it is quite difficult for me to do the same as I am not aware how i should do it some help would be really great
Main class:
package com.example;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import com.example.model.Example;
import com.example.repository.ExampleRepository;
import net.bytebuddy.implementation.bind.annotation.Super;
#SpringBootApplication
public class ExampleApplication implements CommandLineRunner {
#Autowired
ExampleRepository exampleRepository;
public static void main(String[] args) {
SpringApplication.run(ExampleApplication.class, args);
}
#Override
public void run(String... args) throws Exception {
List<Example> example= new ArrayList<>();
// create dummy
example.add(new Example(1,"abc","sachin","abc","abc"));
example.add(new Example(2,"abc","rahul","abc","abc"));
example.add(new Example(3,"abc","rahul","abc","abc"));
exampleRepository.saveAll(example);
}
}
Entity layer:
package com.example.model;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
#Table(name="example")
public class Example{
#Column(name="city")
private String city;
#Column(name="name")
private String name;
#Column(name="amount")
private String amount;
#Column(name="country")
private String country;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name="id")
private long id;
//getter and setters
}
Repository layer is as follows:
package com.example.repository;
import java.util.List;
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.example.model.Example;
#Repository("exampleRepository")
public interface ExampleRepository extends JpaRepository<Example,Long> {
List<Report> findByName(String name);
}
service layer is as follows
package com.example.services;
import java.util.List;
import javax.transaction.Transactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.example.model.Example;
import com.example.repository.ExampleRepository;
#Transactional
#Service
public class ExampleService {
#Autowired
ExampleRepository exampleRepository;
public List<Example> fetchAll() {
return exampleRepository.findAll();
}
public List<Example> findByName(String name){
return exampleRepository.findByName(name);
}
}
I have 2 controllers one to get all details and one to get selective columns and here we are generating csv files based on records that match the name
COntroller 1:
package com.example.controllers;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.opencsv.CSVWriter;
import com.opencsv.bean.StatefulBeanToCsv;
import com.opencsv.bean.StatefulBeanToCsvBuilder;
import com.example.model.Example;
import com.example.services.ExampleService;
#RestController
#RequestMapping("/demo")
public class Controller1 {
#Autowired
ExampleService exampleService;
#GetMapping("/result")
public void exportCSV(#RequestParam(name="name") String name ,HttpServletResponse response) throws Exception {
// set file name and content type
String filename = "names.csv";
response.setContentType("text/csv");
response.setHeader(HttpHeaders.CONTENT_DISPOSITION,
"attachment; filename=\"" + filename + "\"");
// Configure the CSV writer builder
StatefulBeanToCsvBuilder<Example> builder = new StatefulBeanToCsvBuilder<Example>(response.getWriter()).withQuotechar(CSVWriter.NO_QUOTE_CHARACTER).withSeparator(CSVWriter.DEFAULT_SEPARATOR).withOrderedResults(false);
// create a csv writer
StatefulBeanToCsv<Example> writer = builder.build();
// write all employees to csv file
writer.write(examplesService.findByName(name));
}
}
Controller 2:
package com.reports.controllers;
import java.util.Arrays;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.opencsv.CSVWriter;
import com.opencsv.bean.StatefulBeanToCsv;
import com.opencsv.bean.StatefulBeanToCsvBuilder;
import com.example.model.Example;
import com.example.services.ExampleService;
#RestController
#RequestMapping("/example")
public class Controller2 {
#Autowired
ExampleService exampleService;
#GetMapping("/output")
public void exportCSV(#RequestParam(name="name") String name ,HttpServletResponse response) throws Exception {
// set file name and content type
String filename = "details.csv";
response.setContentType("text/csv");
response.setHeader(HttpHeaders.CONTENT_DISPOSITION,
"attachment; filename=\"" + filename + "\"");
// Configure the CSV writer builder
StatefulBeanToCsvBuilder<Example> builder = new StatefulBeanToCsvBuilder<Example>(response.getWriter()).withQuotechar(CSVWriter.NO_QUOTE_CHARACTER).withSeparator(CSVWriter.DEFAULT_SEPARATOR).withOrderedResults(false);
// Ignore any field except the `id` and `amount` ones
Arrays.stream(Example.class.getDeclaredFields())
.filter(field -> !("id".equals(field.getName()) || "amount".equals(field.getName())
))
.forEach(field -> builder.withIgnoreField(Report.class, field));
// create a csv writer
StatefulBeanToCsv<Example> writer = builder.build();
// write all employees to csv file
writer.write(exampleService.findByname(name));
}
}

Try this approach :
generate a file in your /src/test/resources path and then test if it contains the generated data you expected
use combine it with a file system mocking to do it
You will :
test your ResController
mock your Service class
Also use Contructor Injection for you dependency

Related

Deploy issues with data base connection Heroku

I'm working with a project that has the back in Java deployed at Heroku and the front in Angular dpeloyed at Firebase. Data base is in CleverCloud.
I'm having problems with bringing data to the front from the data base.
PERSON TABLE (WORKS JUST FINE):
CONTROLLER (JAVA):
package com.portfoliocardone.portfoliocardone.Controller;
import com.portfoliocardone.portfoliocardone.Entity.Person;
import com.portfoliocardone.portfoliocardone.Interface.IPersonService;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
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.RequestParam;
import org.springframework.web.bind.annotation.RestController;
#RestController
#CrossOrigin(origins = "https://portfoliocardone.web.app")
public class PersonController {
#Autowired IPersonService ipersonService;
#GetMapping("/person/get")
public List<Person> getPerson(){
return ipersonService.getPerson();
}
#PostMapping("/person/new")
public String createPerson(#RequestBody Person person){
ipersonService.savePerson(person);
return "The person was created correctly";
}
#DeleteMapping("/person/delete/{id}")
public String deletePerson(#PathVariable Long id){
ipersonService.deletePerson(id);
return "The person was deleted correctly";
}
//URL:PORT/person/edit/id/name & lastname & img & about me
#PutMapping("/person/edit/{id}")
public Person editPerson(#PathVariable Long id,
#RequestParam("name") String newName,
#RequestParam("lastname") String newLastname,
#RequestParam("img") String newImg,
#RequestParam("aboutme") String newAboutme){
Person person = ipersonService.findPerson(id);
person.setName(newName);
person.setLastname(newLastname);
person.setImg(newImg);
person.setAboutme(newAboutme);
ipersonService.savePerson(person);
return person;
}
#GetMapping("/person/find/profile")
public Person findPerson(){
return ipersonService.findPerson((long)1);
}
}
SERVICE ANGULAR PROJECT:
import { HttpClient } from '#angular/common/http';
import { Injectable } from '#angular/core';
import { Observable } from 'rxjs';
import { person } from '../model/person.model';
#Injectable({
providedIn: 'root'
})
export class PersonService {
URL = 'https://portfoliocardone.herokuapp.com/person/';
constructor(private http:HttpClient) { }
public getPerson(): Observable<person>{
return this.http.get<person>(this.URL+'find/profile');
}
}
After I bring the data to the component by putting {{person.name}}, {{person.lastname}}, {{person.aboutme}} in the html file. I left the image empty and it works just fine.
HERE IS THE PROBLEM WITH THE OTHER TABLE:
CONTROLLER (JAVA):
package com.portfoliocardone.portfoliocardone.Controller;
import com.portfoliocardone.portfoliocardone.Entity.Experience;
import com.portfoliocardone.portfoliocardone.Interface.IExperienceService;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
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.RequestParam;
import org.springframework.web.bind.annotation.RestController;
#RestController
#CrossOrigin(origins = "https://portfoliocardone.web.app")
public class ExperienceController {
#Autowired IExperienceService iexperienceService;
#GetMapping("/experience/get")
public List<Experience> getExperience(){
return iexperienceService.getExperience();
}
#PostMapping("/experience/new")
public String createExperience(#RequestBody Experience experience){
iexperienceService.saveExperience(experience);
return "The experience was created correctly";
}
#DeleteMapping("/experience/delete/{id}")
public String deleteExperience(#PathVariable Long id){
iexperienceService.deleteExperience(id);
return "The experience was deleted correctly";
}
//URL:PORT/experience/edit/id/title & time & location & description
#PutMapping("/experience/edit/{id}")
public Experience editExperience(#PathVariable Long id,
#RequestParam("title") String newTitle,
#RequestParam("time") String newTime,
#RequestParam("location") String newLocation,
#RequestParam("description") String newDescription){
Experience experience = iexperienceService.findExperience(id);
experience.setTitle(newTitle);
experience.setTime(newTime);
experience.setLocation(newLocation);
experience.setDescription(newDescription);
iexperienceService.saveExperience(experience);
return experience;
}
#GetMapping("/experience/find/profile/{id}")
public Experience findExperience(#PathVariable("id") Long id){
return iexperienceService.findExperience((long)id);
}
}
ANGULAR SERVICE
import { HttpClient } from '#angular/common/http';
import { Injectable } from '#angular/core';
import { Observable } from 'rxjs';
import { experience } from '../model/experience.model';
#Injectable({
providedIn: 'root'
})
export class ExperienceService {
URL = 'https://portfoliocardone.herokuapp.com/experience/';
constructor(private http:HttpClient) { }
public getExperience(): Observable<experience>{
return this.http.get<experience>(this.URL+'find/profile/{id}');
}
}
ERRORS I GET IN CONSOLE:
headers: An, status: 400, statusText: 'OK', url:...
Does someone know how to be able to bring the data from this second table? Thanks!

Redis Server is not getting Refreshed

I'm using redis in my springboot rest application to store cache. But the problem I'm facing is once it is stored in redis my api only hits the redis not the database. I've added time out property it didn't work. I've tried CacheManager to get the cache and call CacheEvict to clear the cache and then CachePut to put the data again, but it didn't work. These are the things I've tried so far. I wanted my redis cache to refresh after a given time set by me. Any advice on this? Here is my code below:
package com.dg.repo;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import com.dg.entity.FlightEntity;
public interface FlightRepo extends JpaRepository<FlightEntity, String> {
#Query(value="select distinct txtFlightName\r\n"
+ "from {test-schema}flights", nativeQuery = true)
List<String> getAllFlights();
#Query(value="select distinct txtFlightName from {test-schema}flights \r\n"
+ "where txtFlightName LIKE %:flightname%",nativeQuery = true)
List<String> getListofFlights(#Param("flightname")String flightname);
#Query(value="select distinct txtBookingCode,txtFlightName from {test-schema}flights \r\n"
+ "where txtFlightName LIKE %:flightname%",nativeQuery = true)
List<FlightEntity> getFlightEntity(#Param("flightname")String flightname);
}
package com.dg.repo;
import java.util.List;
import java.util.Optional;
import java.util.function.Function;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.repository.query.FluentQuery.FetchableFluentQuery;
import com.dg.entity.FlightEntity;
public abstract class FlightRepoImpl implements FlightRepo {
RedisTemplate template;
HashOperations hashOperations;
public FlightRepoImpl(RedisTemplate template, HashOperations hashOperations) {
super();
this.template = template;
this.hashOperations = template.opsForHash();
}
#Override
public List<String> getAllFlights() {
return hashOperations.values("FlightModel");
}
#Override
public List<String> getListofFlights(String flightname) {
return (List<String>) hashOperations.get("FlightModel", flightname);
}
}
package com.dg.service;
import org.modelmapper.ModelMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import com.dg.model.FlightModel;
import com.dg.repo.FlightRepo;
public class FlightService {
#Autowired
FlightRepo flightRepo;
#Autowired
ModelMapper modelMapper;
#Scheduled(fixedRate = 50000)
#Caching(evict = {#CacheEvict(value="getFlightList", key="#flightname")})
public FlightModel getFlightByFlightName(String flightName)
{
package com.dg.model;
import java.io.Serializable;
import java.util.List;
public class FlightModel implements Serializable{
private List<Object> listofflightname;
public List<Object> getListofflightname() {
return listofflightname;
}
public void setListofflightname(List<Object> listofflightname) {
this.listofflightname = listofflightname;
}
}
package com.dg.entity;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
#Entity
public class FlightEntity {
#Id
#Column(name="txtBookingCode")
private String bookingCode;
#Column(name="txtFlightName")
private String flightname;
public String getBookingCode() {
return bookingCode;
}
public void setBookingCode(String bookingCode) {
this.bookingCode = bookingCode;
}
public String getFlightname() {
return flightname;
}
public void setFlightname(String flightname) {
this.flightname = flightname;
}
}
package com.dg.config;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.data.redis.connection.RedisClusterConfiguration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.repository.configuration.EnableRedisRepositories;
import redis.clients.jedis.JedisPoolConfig;
#Configuration
#EnableRedisRepositories
#Profile("test")
public class RedisConfig {
#Value("${spring.redis.cluster.nodes}")
private String nodesProperty;
#Bean
public JedisConnectionFactory jedisConnectionFactory()
{
JedisPoolConfig poolConfig = new JedisPoolConfig();
poolConfig.setMinIdle(2);
poolConfig.setMaxIdle(5);
poolConfig.setMaxTotal(20);
poolConfig.setEvictorShutdownTimeoutMillis(10000);
String [] nodesArray=nodesProperty.split(",");
List<String> nodes = new ArrayList<String>(Arrays.asList(nodesArray));
RedisClusterConfiguration configuration=new RedisClusterConfiguration(nodes);
configuration.setMaxRedirects(100);
JedisConnectionFactory connectionFactory = new JedisConnectionFactory(configuration);
connectionFactory.setPoolConfig(poolConfig);
return connectionFactory;
}
#Bean
public RedisTemplate redisTemplate()
{
RedisTemplate template = new RedisTemplate();
template.setConnectionFactory(jedisConnectionFactory());
return template;
}
}
package com.dg;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
#SpringBootApplication
#EnableCaching
public class RedisTestApplication {
public static void main(String[] args) {
SpringApplication.run(RedisTestApplication.class, args);
}
}

Integration testing for events in the Jersey container listener

I have an application based on Jersey JAX-RS. I need to refactor the event handler and therefore also write a test for it.
I'm trying to do this with the JerseyTest Framework. I created a configuration to extend ResourceConfig, but when I use the target () call the handler is not called.
I will present the situation using code.
Here is an example Resource class:
package com.my.page;
import org.glassfish.hk2.api.messaging.Topic;
import com.my.core.entity.Link;
import com.my.core.location.LinkHitLocationFactory;
import com.my.core.service.LinkService;
import com.my.core.service.link.LinkFinder;
import com.my.core.service.link.LinkFinderFactory;
import com.my.event.LinkHitEvent;
import com.my.exception.FragmentNotFoundException;
import javax.annotation.security.PermitAll;
import javax.inject.Inject;
import javax.ws.rs.*;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.Response;
#PermitAll
#Path("/")
public class LinkResource {
#Inject
private LinkService linkService;
#Inject
private Topic<LinkHitEvent> linkHitPublisher;
#Inject
private LinkFinderFactory linkFinderFactory;
#Inject
private LinkHitLocationFactory linkHitLocationFactory;
#GET
#Path("/{fragment:[^ ]{1,32}}")
public Response redirect(
#PathParam("fragment") String fragment,
#HeaderParam("Range") String range,
#HeaderParam("User-Agent") String userAgent,
#Context HttpHeaders headers) throws Exception {
LinkFinder linkFinder = linkFinderFactory.getLinkFinder(fragment);
Link link = linkFinder.getLink(fragment);
if (link.isExpired()) {
throw new FragmentNotFoundException(fragment);
}
linkService.insertHit();
linkHitPublisher.publish(new LinkHitEvent(link));
return handlerFactory.getHandler(link).handleGet(link, range).build();
}
}
Event test:
package com.my.page;
import org.glassfish.hk2.extras.events.internal.TopicDistributionModule;
import org.glassfish.hk2.utilities.binding.AbstractBinder;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.test.JerseyTest;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import pl.comvision.hk2.events.ThreadedEventDistributorService;
import com.my.client.CallbackTargetBuilder;
import com.my.core.entity.Link;
import com.my.core.mapper.LinkMapper;
import com.my.core.service.LinkService;
import com.my.page.resource.LinkResource;
import javax.ws.rs.core.Application;
import javax.ws.rs.core.Response;
import static javax.ws.rs.core.Response.Status.TEMPORARY_REDIRECT;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.*;
#RunWith(MockitoJUnitRunner.class)
public class CallbackEventTest extends JerseyTest {
#Mock
private LinkMapper linkMapper;
#Mock
private LinkService linkService;
private CallbackTargetBuilder callbackTargetBuilder;
private final String callbackUrl = "";
#Override
protected Application configure() {
this.callbackTargetBuilder = spy(new CallbackTargetBuilder(this.callbackUrl));
ResourceConfig config = new ResourceConfig(LinkResource.class);
config.register(new TopicDistributionModule());
config.register(new AbstractBinder() {
#Override
protected void configure() {
addActiveDescriptor(ThreadedEventDistributorService.class).setRanking(100);
}
});
config.register(new EventsContainerListener(CallbackEventHandler.class));
config.register(new AbstractBinder() {
#Override
protected void configure() {
bind(linkMapper).to(LinkMapper.class);
bind(linkService).to(LinkService.class);
bind(mock(LinkService.class)).to(LinkService.class);
bind("").to(String.class).named("varPath");
bind("127.0.0.1").to(String.class).named("requestIP");
bind(callbackTargetBuilder).to(CallbackTargetBuilder.class);
}
});
return config;
}
#Test
public void publish_event() {
Link link = mock(Link.class);
when(link.getUrl()).thenReturn("example");
when(link.getName()).thenReturn("test");
when(linkMapper.getByName(anyString())).thenReturn(link);
Response response = target("/testY").property("jersey.config.client.followRedirects", false).request().get();
assertEquals(TEMPORARY_REDIRECT.getStatusCode(), response.getStatus());
verify(callbackTargetBuilder).build();
}
}
For testing purposes, I only injected callbackTargetBuilder into the handler, and called the build method on it to verify the call:
package com.my.page;
import org.glassfish.hk2.api.messaging.MessageReceiver;
import org.glassfish.hk2.api.messaging.SubscribeTo;
import org.jvnet.hk2.annotations.Service;
import com.my.client.CallbackTargetBuilder;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.core.Form;
import javax.ws.rs.core.MediaType;
#Service
#Singleton
#MessageReceiver
public class CallbackEventHandler {
#Named("callbackUrl")
private String url;
#Inject
private CallbackTargetBuilder callbackTargetBuilder;
#MessageReceiver
public void handle(#SubscribeTo LinkHitEvent event) {
Form form = new Form();
form.param("id", event.getLink().getId().toString());
form.param("name", event.getLink().getName());
callbackTargetBuilder.build();
Client client = ClientBuilder.newClient();
client.target(url).request().post(Entity.entity(form, MediaType.APPLICATION_FORM_URLENCODED_TYPE));
}
}
Edit:
I tried to register dependencies differently, but it does not bring satisfactory results. Each time verification fails:
verify (callbackTargetBuilder) .build ();
Looking for information I found that I can configure the DeploymentContext, but I don't know if this is the right direction.
Edit the second:
A quick test shows that I may have some more basic problem with mocking. Because the call:
verify (linkService) .insertHit (anyObject ());
It also fails.
I will write only for posterity that the above code is correct. The problem was a lot of small bugs in the tested code and how to mock it.

Dependency Injection in JHipster with Mybatis

I have little problem with Spring and Mybatis connection in JHipster framework( (out of the box).
Problem is occurred when I try inject class, which have Mybatis mapper injected. In this situation class returns null pointer exception. When I try to autowire this class I get "cannot find candidate to autowire error".
Architecture of class:
Repository(Mybatis mapper interface) ->
ServiceImplementation (Class with injected Mybatis Repository, business logic) ->
Resource (REST controller with instance of Service)
I think solution is simple, but I cannot find right implementation:
Service Implementation is invisible for Spring Beans Mapper and I
can't find in JHipster configuration for them.
I have to use another annotation to get right injection of Service
Implemenation
Somebody meet with this situation and can get litte clue for me to refactor my code? :-) Thanks
Code:
Repository
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.apache.ibatis.annotations.Insert;
import java.util.List;
import org.apache.ibatis.annotations.Delete;
import pl.xxx.xxx.domain.City;
import pl.xxx.xxx.domain.Dish;
#Mapper
public interface CityMapper {
#Select("SELECT * FROM CITY WHERE id = #{id}")
City getCityByID(#Param("id") Long id);
#Select("SELECT * FROM CITY WHERE name = #{name}")
City getCityByName(#Param("name") String name);
#Insert("INSERT INTO CITY('name') VALUES(#{name})")
void createCity(City city);
#Delete("DELETE FROM CITY WHERE id = #{id}")
void deleteCityByID(City city);
#Select("SELECT count(*) FROM CITY")
int getNumberOfCities();
#Select("<script>"
+ "SELECT * FROM CITY "
+ "</script>")
List<City> findAll();
}
Service
package pl.xxx.xxx.service.impl;
import java.util.List;
import javax.inject.Inject;
import pl.xxxx.xxxx.domain.City;
import pl.xxxx.xxx.repository.CityMapper;
import pl.xxx.xxx.service.CityService;
import pl.xxx.xxx.web.rest.util.Pageable;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
import org.springframework.context.annotation.Bean;
#Service
#Transactional
public class CityServiceImpl implements CityService {
#Inject
private CityMapper cityMapper;
#Override
public List<City> findAll(Pageable pageable) {
return cityMapper.findAll();
}
}
Interface
package pl.xxx.xxx.service;
import java.util.List;
import pl.xxx.xxx.domain.City;
import pl.xxxx.xxx.domain.Dish;
import pl.xxx.xxx.web.rest.util.Pageable;
public interface CityService {
/**
* Get all the dishes.
*
* #param pageable the pagination information
* #return the list of entities
*/
List<City> findAll(Pageable pageable);
}
Resource
package pl.xxx.xxxx.web.rest;
import com.codahale.metrics.annotation.Timed;
import pl.xxx.xxx.xxx.City;
import pl.xxx.xxx.domain.Dish;
import pl.xxx.xxx.repository.CityMapper;
import pl.xxx.xxx.service.impl.CityServiceImpl;
import pl.xxx.xxx.web.rest.util.Pageable;
import pl.xxx.xxx.web.rest.util.PaginationUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;
import javax.annotation.Resource;
import javax.inject.Inject;
import static org.elasticsearch.index.query.QueryBuilders.*;
/**
* REST controller for managing City.
*/
#RestController
#RequestMapping("/api")
public class CityResource {
private final Logger log = LoggerFactory.getLogger(CityResource.class);
private CityServiceImpl cityServiceImpl;
#Inject
private CityMapper cityMapper;
/**
* GET /Cities: get all the cities.
*
* #param pageable the pagination information
* #return the ResponseEntity with status 200 (OK) and the list of citires in body
* #throws URISyntaxException if there is an error to generate the pagination HTTP getHeaders()
*/
#RequestMapping(value = "/cities",
method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_VALUE)
#Timed()
public ResponseEntity<List<City>> getAllCities(Pageable pageable)
throws URISyntaxException {
log.debug("REST request to get a page of Cities");
Pageable p = new Pageable();
List<City> page = cityServiceImpl.findAll(p);
HttpHeaders headers = PaginationUtil.generateSearchPaginationHttpHeadersLM("/api/cities");
return new ResponseEntity<>(page, headers, HttpStatus.OK);
}
}

Spring MockMvc redirectedUrl with pattern

I have a simple PersonController class that provides save() method to persist the object from http post request.
package org.rw.controller;
import java.sql.Timestamp;
import java.util.List;
import org.rw.entity.Person;
import org.rw.service.PersonService;
import org.rw.spring.propertyeditor.TimestampPropertyEditor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
#Controller
#RequestMapping(value="/person")
public class PersonController {
private static final Logger logger = LoggerFactory.getLogger(PersonController.class);
#Autowired
private PersonService personService;
#Autowired
TimestampPropertyEditor timestampPropertyEditor;
#InitBinder
public void initBinder(WebDataBinder binder) {
binder.registerCustomEditor(Timestamp.class, "dob", timestampPropertyEditor);
}
#RequestMapping(value="/save", method=RequestMethod.POST)
public String save(Model model, Person person) {
Long personId = personService.save(person);
return "redirect:view/" + personId;
}
}
As the save() method returns as return "redirect:view/" + personId;. It will be diffrerent for every request. it may be like "view/5" or "view/6" depending on the id of the object that has been persisted.
Then i have a simple class to test the above controller with spring mocking.
package org.rw.controller;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.redirectedUrl;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import org.junit.Test;
import org.rw.service.UserService;
import org.rw.test.SpringControllerTest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
public class PersonControllerTest extends SpringControllerTest {
#Autowired
private UserService userService;
#Test
public void add() throws Exception {
mockMvc.perform(get("/person/add", new Object[0])).andExpect(status().isOk());
}
#Test
public void save() throws Exception {
UserDetails userDetails = userService.findByUsername("anil");
Authentication authToken = new UsernamePasswordAuthenticationToken (userDetails.getUsername(), userDetails.getPassword(), userDetails.getAuthorities());
SecurityContextHolder.getContext().setAuthentication(authToken);
mockMvc.perform(
post("/person/save", new Object[0])
.param("firstName", "JunitFN")
.param("lastName", "JunitLN")
.param("gender", "M")
.param("dob", "11/02/1989")
).andExpect(
redirectedUrl("view")
);
}
}
now here i have a problem that redirectedUrl("view") is rejecting value "view/5". I have tried redirectedUrl("view*") and redirectedUrl("view/*") but its not working.
Edit :
Here I have got a workaround as per below
MvcResult result = mockMvc.perform(
post("/person/save", new Object[0])
.param("firstName", "JunitFN")
.param("lastName", "JunitLN")
.param("gender", "MALE")
.param("dob", "11/02/1989")
).andExpect(
//redirectedUrl("view")
status().isMovedTemporarily()
).andReturn();
MockHttpServletResponse response = result.getResponse();
String location = response.getHeader("Location");
Pattern pattern = Pattern.compile("\\Aview/[0-9]+\\z");
assertTrue(pattern.matcher(location).find());
but still i am looking for the proper way.
update:
I have posted the same issue on spring jira here :
Since spring 4.0 you can use redirectedUrlPattern as pointed by Paulius Matulionis
As of spring 3.x this is not supported out of the box but you can easily add you custom result matcher
private static ResultMatcher redirectedUrlPattern(final String expectedUrlPattern) {
return new ResultMatcher() {
public void match(MvcResult result) {
Pattern pattern = Pattern.compile("\\A" + expectedUrlPattern + "\\z");
assertTrue(pattern.matcher(result.getResponse().getRedirectedUrl()).find());
}
};
}
And use it like build-in matcher
mockMvc.perform(
post("/person/save", new Object[0])
.param("firstName", "JunitFN")
.param("lastName", "JunitLN")
.param("gender", "M")
.param("dob", "11/02/1989")
).andExpect(
redirectedUrlPattern("view/[0-9]+")
);
Since 4.0 it is available in Spring itself.
Please check here.

Categories

Resources