RestFulClient CRUDRepository Implementation - spring-boot

I am using SpringBoot to write web service client. How to use CRUDRepository inside the client? I have to save the data from the webservice to a database table? How do I get the handle to BookRepository inside my client?
public interface BookRepository extends CrudRepository<BooksStage, Long> {}
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<Books[]> responseEntity = restTemplate.getForEntity("http://localhost:8080/booksList", Books[].class);
Books[] books=responseEntity.getBody();
if(books!=null){
log.info("booksreceived -"+books.length);
for (Books c : books){
//Insert into database
}
}

1) Interface BookRepository shall be annotated with #Repository. You should autowire interface BookRepository in your Web Service Client class.
2) The RestTemplate shall be inside a Web Service Client class annotated with #Service
3) Since your entity name is BooksStage, you should only save entity of type BooksStage (and not Books).
#Repository
public interface BookRepository extends CrudRepository<BooksStage, Long> {
}
#Service
public class MyWebServiceClient{
#Autowired
private BookRepository bookRepo;
public boolean updateSomeBook() {
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<BooksStage[]> responseEntity =
restTemplate.getForEntity ("http://localhost:8080/booksList", Books[].class);
BooksStage[] books=responseEntity.getBody();
if(books!=null){
log.info("booksreceived -"+books.length);
for (BooksStage c : books){
bookRepo.save(c);
}
return true;
}
}
#Entity
#Table(name = "books_stage")
public class BooksStage {
#Id
#Column(name = "ID")
private long id;
//other related fields
}

Related

Mockito injecting mocks Spring Boot test

Hi I have a service class that contains mapper and repository:
#Service
public class ProductServiceImp implements ProductService {
#Autowired
private ProductRepository repository;
#Autowired
private WarehouseApiMapper mapper;
public ProductServiceImp(ProductRepository repository) {
this.repository = repository;
}
}
Repository:
#Repository
public interface ProductRepository extends JpaRepository<Product, Integer> {
}
Mapper:
#Mapper(componentModel = "spring")
public interface WarehouseApiMapper {
WarehouseApiMapper mapper = Mappers.getMapper(WarehouseApiMapper.class);
Product ProductDtoToProduct(ProductDto productDto);
ProductDto ProductToProductDto(Product product);
}
In test class I would like to inject mock repository and autowired mapper
Here is my test class:
#SpringBootTest
public class ProductServiceTest {
#Mock
ProductRepository repository;
#InjectMocks
ProductServiceImp service;
#ParameterizedTest
#MethodSource("provideParametersProductUpdate")
void assert_that_product_is_updated_correctly(String productName, BigDecimal productPrice) {
Product oldProduct = new Product("Product that does not exist", BigDecimal.valueOf(1000000), null);
oldProduct.setId(1);
Mockito.when(repository.findById(1)).thenReturn(Optional.of(oldProduct));
Product newProduct = new Product(productName, productPrice, null);
newProduct.setId(1);
ProductDto updatedProduct = service.updateProduct(newProduct);
Assertions.assertEquals(productPrice, updatedProduct.getPrice());
Assertions.assertEquals(productName, updatedProduct.getName());
}
private static Stream<Arguments> provideParametersProductUpdate() {
return Stream.of(
Arguments.of("dark chocolate", BigDecimal.valueOf(3.2)),
Arguments.of("chewing gum", BigDecimal.valueOf(1.2)),
Arguments.of("lollipop", BigDecimal.valueOf(4.0))
);
}
}
Code throws NullPointerException when is trying to map object in service method.
Somebody knows how can I inject this? Thanks for ur answers
If you want to create just a Mockito test you could use the annotation #RunWith(MockitoJUnitRunner.class) instead of #SpringBootTest.
But if you want to create a Spring Boot integration test then you should use #MockBean instead of #Mock and #Autowired instead of #InjectMocks.

#Qualifier & #Autowired object coming as null

I am having following code below.
#Builder(toBuilder = true)
#AllArgsConstructor(access = AccessLevel.PRIVATE)
#NoArgsConstructor(access = AccessLevel.PRIVATE)
#ToString
#EqualsAndHashCode
#Configurable
public class Employee {
#Autowired
#Qualifier("findEmpByDepartment")
private Function<Long, Long> empByDepartment;
private void save() {
this.empByDepartment.getList();
}
}
and FindEmpByDepartment class below.
#Component("findEmpByDepartment")
public class FindEmpByDepartment implements Function<Long, Long> {
public void getList() {
}
....
}
My problem is I am always getting null when invoke
this.empByDepartment.getList();
line. Here this.empByDepartment is coming as null. Any idea why it is like this?
Thanks
May be you would have missed annotating any class in the flow hierarchy .
#Service, #Repository and #Controller are all specializations of #Component, so any class you want to auto-wire needs to be annotated with one of them.
IoC is like the cool kid on the block and if you are using Spring then you need to be using it all the time .
So make sure you do not have any object created with new operator in the entire flow .
#Controller
public class Controller {
#GetMapping("/example")
public String example() {
MyService my = new MyService();
my.doStuff();
}
}
#Service
public class MyService() {
#Autowired
MyRepository repo;
public void doStuff() {
repo.findByName( "steve" );
}
}
#Repository
public interface MyRepository extends CrudRepository<My, Long> {
List<My> findByName( String name );
}
This will throw a NullPointerException in the service class when it tries to access the MyRepository auto-wired Repository, not because there is anything wrong with the wiring of the Repository but because you instantiated MyService() manually with MyService my = new MyService().
For more details , you can check
https://www.moreofless.co.uk/spring-mvc-java-autowired-component-null-repository-service/

Testing service layer in Spring Boot using Mockito

I am trying to unit test my service layer using mockito having a connection to a Database through the Repository layer.
My test case:
#InjectMocks
private EmployeeService employeeService;
#Mock
private EmployeeRepository employeeRepository;
#Test
public void getActionFromEmployeeIdTest() throws ActionException {
//setup
when(employeeRepository.getActionsByEmployeeId(anyLong()).thenReturn(EmployeeEntity);
// exercise
List<Employee> result = employeeService.getActionsByEmployeeIdService(101);
//verify
assertEqual(EmployeeEntity, result);
}
Service Layer:
#Service
public class EmployeeService {
#Override
public List<EmployeeUser> getActionsByEmployeeIdService(long employeeId) {
Employee employee = employeeRepository.findByEmployeeIdId(employeeId);
List<EmployeeUser> actions = employeeUserRepository.getActionsByEmployeeId(employeeId);
return actions;
}
Repository layer:
#Repository
public interface EmployeeUserRepository extends JpaRepository<EmployeeUser,Long> {
#Transactional
#Query(value = "Select e from EmployeeUser e where e.employeeId = :employeeId" )
List<EmployeeUser> getActionsByEmployeeId(#Param("employeeId") long employeeId);
}
I am using #InjectMocks for employeeService and #Mock for employeeRepository.
result seems to be returning null. Is there anyway I can return a non-null value in my test?
You are using reference of employeeRepository to call getActionssByEmployeeId(anyLong()) method.
when(employeeRepository.getActionssByEmployeeId(anyLong()).thenReturn(EmployeeEntity);
But in service calss this methos is getting called by employeeUserRepository
List<EmployeeUser> actions = employeeUserRepository.getActionsByEmployeeIdId(employeeId);
Please check this.

Spring Data Rest testing

I'm developing the application by using Spring Data Rest. As you know, after creating simple repository interfaces, rest-endpoints are created by library.
Do I need to test these endpoints by integration tests? If yes, please provide any examples
here is the code snippet. read the full tutorial here
#Entity
#Table(name = "person")
public class Employee {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#Size(min = 3, max = 20)
private String name;
// standard getters and setters, constructors
}
#Repository
public interface EmployeeRepository extends JpaRepository<Employee, Long> {
public Employee findByName(String name);
}
#RunWith(SpringRunner.class)
#SpringBootTest(
SpringBootTest.WebEnvironment.MOCK,
classes = Application.class)
#AutoConfigureMockMvc
#TestPropertySource(
locations = "classpath:application-integrationtest.properties")
public class EmployeeRestControllerIntegrationTest {
#Autowired
private MockMvc mvc;
#Autowired
private EmployeeRepository repository;
#Test
public void givenEmployees_whenGetEmployees_thenStatus200()
throws Exception {
createTestEmployee("bob");
mvc.perform(get("/api/employees")
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(content()
.contentTypeCompatibleWith(MediaType.APPLICATION_JSON))
.andExpect(jsonPath("$[0].name", is("bob")));
}
}
Aside from regular testing you can do with Spring (using MockMvc, RestAssured, RestTemplate etc), Traverson is a great API for specifically testing Spring HATEOAS. You can use it to test the validity of the links you are returning to your clients, see this example

Adding web sockets support to spring data rest events

I have spring data rest repositories with the default post and update and delete.
I have also implemented an Event handler, now how can I add Web sockets to the event handlers?
#RepositoryEventHandler(User.class)
#Service
public class UserEventHandler {
private static final Logger LOG = LoggerFactory.getLogger(UserEventHandler.class);
#Autowired
private SmtpMailSender smtpMailSender;
#HandleAfterCreate
public void handleBeforeCreate(User u) {
}
}
// Repository class
#Transactional
#RepositoryRestResource(path = "users", collectionResourceRel = "users")
public interface UserRepository extends PagingAndSortingRepository<User, String> {
}

Resources