I have encountered a very strange exception when I was learning AOP in Spring.
Here are my codes:
CompactDisc Interface:
public interface CompactDisc {
void play();
}
BlankDisc class:
import org.springframework.stereotype.Component;
import java.util.List;
#Component
public class BlankDisc implements CompactDisc {
private String title;
private String artist;
private List<String> tracks;
public BlankDisc(String title, String artist, List<String> tracks) {
this.title = title;
this.artist = artist;
this.tracks = tracks;
}
#Override
public void play() {
System.out.println("Playing "+title+" by "+artist);
for (String track : tracks)
System.out.println("-Track "+track);
}
public void playTrack(int trackNumber) {
System.out.println("-Track "+tracks.get(trackNumber));
}
TrackCounter class
package soundsystem;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import java.util.HashMap;
import java.util.Map;
#Aspect
public class TrackCounter {
private Map<Integer,Integer> trackCounts = new HashMap<>();
#Pointcut("execution(* BlankDisc.playTrack(int)) " +
"&& args(trackNumber)")
public void trackPlayed(int trackNumber) {}
#Before("trackPlayed(trackNumber)")
public void countTrack(int trackNumber) {
int currentCount = getPlayCount(trackNumber);
trackCounts.put(trackNumber, currentCount + 1);
}
public int getPlayCount(int trackNumber) {
return trackCounts.getOrDefault(trackNumber, 0);
}
}
TrackCounterConfig class
package soundsystem;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import java.util.ArrayList;
import java.util.List;
#Configuration
#EnableAspectJAutoProxy
public class TrackCounterConfig {
#Bean(name = "compactDisc")
public BlankDisc blankDisc() {
List<String> list= new ArrayList<>(5);
list.add("Sgt.Pepper's Lonely Hearts Club Band");
list.add("With a Little Help from My Friends");
list.add("Lucy in the Sky with Diamonds");
list.add("Getting Better");
list.add("Fixing a Hole");
return new BlankDisc("Sgt.Pepper's Lonely Hearts Club Band","The Beatles",list);
}
#Bean
public TrackCounter trackCounter() {
return new TrackCounter();
}
}
TrackCounterTest class:
import static org.junit.Assert.*;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import soundsystem.*;
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(classes = TrackCounterConfig.class)
public class TrackCounterTest {
#Autowired
private BlankDisc cd;
#Autowired
private TrackCounter counter;
#Test
public void testTrackCounter() {
//Question: cd must be CompactDisc not BlankDisc,
//otherwise will cause type exception, why?
cd.playTrack(0);
cd.playTrack(1);
cd.playTrack(2);
cd.playTrack(3);
cd.playTrack(3);
cd.playTrack(3);
cd.playTrack(3);
cd.playTrack(4);
assertEquals(1,counter.getPlayCount(1));
assertEquals(1,counter.getPlayCount(0));
assertEquals(1,counter.getPlayCount(2));
assertEquals(4,counter.getPlayCount(3));
assertEquals(1,counter.getPlayCount(4));
}
}
I ran the test,then I had the exception:
Caused by: org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'compactDisc' is expected to be of type 'soundsystem.BlankDisc' but was actually of type 'com.sun.proxy.$Proxy22'
at org.springframework.beans.factory.support.DefaultListableBeanFactory.checkBeanNotOfRequiredType(DefaultListableBeanFactory.java:1510)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1489)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1104)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:585)
The problems are:
1.If I change the type of cd in TrackCounterTest from BlankDisc to CompactDisc, the exception will not occur, why?
2.After the first problem being solved, if I haven't declared the method void playTrack(int) in the interface CompactDisc, the assertEquals() in test class will fail. That is, AOP does not work, why?
I have been spent a whole day working on this problem and after searching on the google I still could not be able to find the answer. Since I am a rookie in Spring, I sincerely hope that someone could help me to figure this out.
Thank you!!!
This issue is because of autowiring the bean of type class instead do for implemented interface:
Please check this stackoverflow link which explains the same issue:
BeanNotOfRequiredTypeException issue stackoverflow explanation
Related
I am practising restful api endpoints using https://api.predic8.de/shop/docs
Here is my repo
I am getting a NPE failure when I try to use #InjectMocks during my TDD approach
However, I can make my test pass when I make a direct call in the setup()
vendorService = new VendorServiceImpl(VendorMapper.INSTANCE, vendorRepository);
I wanted to extend my learning by trying to create an endpoint for getting all vendors.
When I employ TDD along the way, but, my test getAllVendors() fails on a NPE when I try to use #InjectMocks but passes when I substitute it for a direct call in the setup() method.
The NPE is linked to the mapper class I think.
Here are the classes that I believe are useful. VendorServiceTest, VendorServiceImpl, VendorMapper.
I have commented out the direct call in the setup as I want to get the test passing using #InjectMocks
package guru.springfamework.services;
import guru.springfamework.api.v1.mapper.VendorMapper; import
guru.springfamework.api.v1.model.VendorDTO; import
guru.springfamework.domain.Vendor; import
guru.springfamework.repositories.VendorRepository; import
org.junit.Before; import org.junit.Test; import
org.mockito.InjectMocks; import org.mockito.Mock; import
org.mockito.MockitoAnnotations; import
org.springframework.test.web.servlet.MockMvc;
import java.util.Arrays; import java.util.List;
import static org.junit.Assert.*; import static
org.mockito.Mockito.when;
public class VendorServiceTest {
public static final String NAME = "Tasty";
public static final Long ID = 1L;
#Mock
VendorMapper vendorMapper;
#Mock
VendorRepository vendorRepository;
#InjectMocks
VendorServiceImpl vendorService;
//VendorService vendorService;
#Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
//vendorService = new VendorServiceImpl(VendorMapper.INSTANCE, vendorRepository);
}
#Test
public void getAllVendors() {
//given
List<Vendor> vendors = Arrays.asList(new Vendor(), new Vendor(), new Vendor());
when(vendorRepository.findAll()).thenReturn(vendors);
//when
List<VendorDTO> vendorDTOList = vendorService.getAllVendors();
//then
assertEquals(3, vendorDTOList.size());
}
#Test
public void findByName() {
}
}
package guru.springfamework.services;
import guru.springfamework.api.v1.mapper.VendorMapper; import
guru.springfamework.api.v1.model.VendorDTO; import
guru.springfamework.repositories.VendorRepository; import
org.springframework.stereotype.Service;
import java.util.List; import java.util.stream.Collectors;
#Service public class VendorServiceImpl implements VendorService {
private final VendorMapper vendorMapper;
private final VendorRepository vendorRepository;
public VendorServiceImpl(VendorMapper vendorMapper, VendorRepository vendorRepository) {
this.vendorMapper = vendorMapper;
this.vendorRepository = vendorRepository;
}
#Override
public List<VendorDTO> getAllVendors() {
return vendorRepository
.findAll()
.stream()
.map(vendor -> {
VendorDTO vendorDTO = vendorMapper.vendorToVendorDTO(vendor);
vendorDTO.setVendorUrl("/api/v1/vendors/" + vendor.getId());
return vendorDTO;
})
.collect(Collectors.toList());
}
#Override
public VendorDTO findByName(String name) {
return vendorMapper.vendorToVendorDTO(vendorRepository.findByName(name));
}
#Override
public VendorDTO getVendorById(Long id) {
return vendorMapper.vendorToVendorDTO(vendorRepository.findById(id).orElseThrow(RuntimeException::new));
}
}
package guru.springfamework.api.v1.mapper;
import guru.springfamework.api.v1.model.VendorDTO; import
guru.springfamework.domain.Vendor; import org.mapstruct.Mapper; import
org.mapstruct.factory.Mappers;
#Mapper public interface VendorMapper {
VendorMapper INSTANCE = Mappers.getMapper(VendorMapper.class);
VendorDTO vendorToVendorDTO(Vendor vendor);
}
Does anyone know where and why I am going wrong?
The problem is that you created mock object for the mapper, but you didn't say what should happen when the method vendorToVendorDTO is called.
Therefore, when that method is called in the next line of code:
VendorDTO vendorDTO = vendorMapper.vendorToVendorDTO(vendor);
It will return null, and then in this line of code:
vendorDTO.setVendorUrl("/api/v1/vendors/" + vendor.getId());
You will get NullPointerException.
To make this work, change your getAllVendors() method as follows:
#Test
public void getAllVendors() {
//given
List<Vendor> vendors = Arrays.asList(new Vendor(), new Vendor(), new Vendor());
VendorDTO mockDto = mock(VendorDTO.class);
when(vendorRepository.findAll()).thenReturn(vendors);
when(vendorMapper.vendorToVendorDTO(any(Vendor.class))).thenReturn(mockDto);
//when
List<VendorDTO> vendorDTOList = vendorService.getAllVendors();
//then
assertEquals(3, vendorDTOList.size());
}
And the test should pass.
Have you tried to put #RunWith(MockitoJUnitRunner.class)/#ExtendsWith(MockitoExtension.class) over your test class?
I have encountered an interesting yet a terrifying situation. My application has two features namely, OtpListener and CdmMonitor running on two separate threads. For now, only the OtpListener feature was required so I commented out CdmMonitor in the main class.
However, I still see the logs for the commented out class CdmMonitorService. This service was running (when it shouldn't as it was commented)
Do threads implemented from the Runnable class operate this way? I did not find anything of the sort in its documentation.
Main Class: OtpTrackerApp.java
package dev.xfoil.otpTracker;
import dev.xfoil.otpTracker.service.CdmMonitorService;
import dev.xfoil.otpTracker.service.OTPListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
#SpringBootApplication
#ComponentScan({"dev.xfoil.otpTracker.*","dev.xfoil.shared.*", "dev.xfoil.shared.dal.repositories.springdata.*", "dev.xfoil.shared.dal.entities.*","dev.xfoil.shared.dal.cache.*"})
public class OtpTrackerApp implements CommandLineRunner {
#Autowired
public OTPListener otpListener;
// #Autowired
// public CdmMonitorService cdmMonitorService;
public static void main(String[] args){
SpringApplication.run(OtpTrackerApp.class, args);
}
#Override
public void run(String... args) throws Exception {
// Thread monitoringThread = new Thread(cdmMonitorService);
// monitoringThread.start();
otpListener.startListening();
}
}
CdmMonitorService.java
package dev.xfoil.otpTracker.service;
import com.google.common.flogger.FluentLogger;
import dev.xfoil.otpTracker.firebase.FirestoreManager;
import dev.xfoil.shared.dal.repositories.springdata.MachineMonitorRepo;
import dev.xfoil.shared.dal.repositories.springdata.MachineOperationsHistoryRepo;
import dev.xfoil.shared.dal.repositories.springdata.MachinesRepo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
#Service
public class CdmMonitorService implements Runnable {
FluentLogger logger = FluentLogger.forEnclosingClass();
#Autowired
MachineMonitorRepo machineMonitorRepo;
#Autowired
MachineOperationsHistoryRepo machineOperationsHistoryRepo;
#Autowired
MachinesRepo machinesRepo;
#Autowired
FirestoreManager firestoreManager;
public CdmMonitorService() {
}
#Override
#Scheduled(fixedDelay = 120000l)
public void run() {
try {
// code removed for brevity
Thread.sleep(10000);
} catch (Exception e) {
e.printStackTrace();
logger.atWarning().log("Exception in CDM Monitor Thread " + e);
}
}
}
OtpListener.java
package dev.xfoil.otpTracker.service;
import com.google.common.flogger.FluentLogger;
import dev.xfoil.shared.dal.entities.AccountLedger;
import dev.xfoil.shared.dal.models.OTP;
import dev.xfoil.shared.dal.repositories.springdata.LedgerRepo;
import dev.xfoil.shared.dal.repositories.springdata.NoteCountRepo;
import dev.xfoil.shared.dal.repositories.springdata.UtilRepo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
#Service
public class OTPListener {
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
#Autowired
UtilRepo utilRepo;
#Autowired
ThirdPartyApiCalls discordServer;
#Autowired
NoteCountRepo noteCountRepo;
private static LocalDateTime latestOTPTime;
#Value("#{${webhooks}}")
HashMap<String, String> discordLink = new HashMap<String, String>();
#PostConstruct
public LocalDateTime getLatestOTPTimestamp() {
latestOTPTime = utilRepo.getTimeOfLatestOTP();
return latestOTPTime;
}
public void startListening() throws InterruptedException {
logger.atInfo().log("Current in-mem links:");
try {
// code commented for brevity
Thread.sleep(5 * 60 * 1000);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
I am building a REST API to access a database and having trouble / consistently getting a whitepage error. Running in circles trying to find my error and/or my error in the flow or logic of the program.
Here is my application:
package com.skilldistillery.myRest;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
#SpringBootApplication
#ComponentScan(basePackages= {"com.skilldistillery.edgemarketing"})
#EntityScan("com.skilldistillery.edgemarketing")
#EnableJpaRepositories("com.skilldistillery.myRest.repositories")
public class MyRestApplication extends SpringBootServletInitializer {
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(MyRestApplication.class);
}
public static void main(String[] args) {
SpringApplication.run(MyRestApplication.class, args);
}
}
My controller:
package com.skilldistillery.myRest.controllers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.skilldistillery.edgemarketing.entities.House;
import com.skilldistillery.myRest.services.HouseService;
#RestController
#RequestMapping("api")
#CrossOrigin({ "*", "http://localhost:4200" })
public class HouseController {
#Autowired
HouseService houseServ;
#GetMapping("index/{id}")
public House show(#PathVariable("id") Integer id) {
return houseServ.show(id);
}
}
My repo:
package com.skilldistillery.myRest.repositories;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import com.skilldistillery.edgemarketing.entities.House;
#Repository
public interface HouseRepo extends JpaRepository<House, Integer> {
}
My service:
package com.skilldistillery.myRest.services;
import java.util.List;
import org.springframework.stereotype.Service;
import com.skilldistillery.edgemarketing.entities.House;
#Service
public interface HouseService {
List<House> index();
House show(Integer id);
}
And my ServiceImpl:
package com.skilldistillery.myRest.services;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.skilldistillery.edgemarketing.entities.House;
import com.skilldistillery.myRest.repositories.HouseRepo;
#Service
public class HouseServiceImpl {
#Autowired
HouseRepo hRepo;
public House show(Integer id) {
Optional<House> opt = hRepo.findById(id);
House house = null;
if (opt.isPresent()) {
house = opt.get();
}
return house;
}
}
It compiles and launches but via postman and browser, I am getting whitepage errors. I've scoured the internets trying to understand where I'm going wrong but not finding it. Please advise.
You can use the following solution.
Change your main class to the following code
#SpringBootApplication
public class MyrestapplicationApplication {
public static void main(String[] args) {
SpringApplication.run(MyrestapplicationApplication.class, args);
}
}
Then create a separate class for your configurations.As well as running away from tight coupled architecture.
#Configuration
#EntityScan("com.skilldistillery.edgemarketing.entities")
#EnableJpaRepositories("com.skilldistillery.myRest.repositories")
public class BusinessConfig {
#Bean
public HouseService houseService(final HouseRepo houseRepo){
return new HouseServiceImpl(houseRepo);
}
}
Your controller will then change to the following.Utilising Dependency Injection
#RestController
#RequestMapping("api")
#CrossOrigin({ "*", "http://localhost:4200" })
public class HouseController {
private HouseService houseServ;
public HouseController(HouseService houseServ) {
this.houseServ = houseServ;
}
#GetMapping(value = "index/{id}",produces = MediaType.APPLICATION_JSON_VALUE,consumes = MediaType.APPLICATION_JSON_VALUE)
public House show(#PathVariable("id") Integer id) {
return houseServ.show(id);
}
}
HouseServiceImpl should also implement HouseService
public class HouseServiceImpl implements HouseService{
private HouseRepo hRepo;
public HouseServiceImpl(HouseRepo hRepo) {
this.hRepo = hRepo;
}
#Override
public List<House> index() {
return null;
}
public House show(Integer id) {
Optional<House> opt = hRepo.findById(id);
House house = new House();
if (opt.isPresent()) {
house = opt.get();
}
return house;
}
}
*NB - don't forget to remove the following configs #Autowired,#Repository as they are now handled within the BusinessConfig class.More Beans can be defined in the BusinessConfig Class
I am coding in spring-boot. I tried to get the value of properties.properties in other packages without success. For example in the classe ClassUtils.java, the value of testValue is always null
This is my project
This is my code:
package com.plugins.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import com.plugins.domain.ClassUtils;
#RestController
public class SearchContactController {
#Value("${environnement.test}")
String testValue;
#Value("${environnement.url}")
String urlValue;
#RequestMapping(value = "/test")
public String pingRequest() {
System.out.println("value ===> " + testValue + " /// " + urlValue);
return "test !" + ClassUtils.getTestValue();
}
}
This is my second class, where I can't get the value of testValue variable:
package com.plugins.domain;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
#Component
public class ClassUtils {
#Value("${environnement.test}")
static String testValue;
public static String getTestValue(){
return "The return "+testValue;
}
}
This is my springApp.java
package com.plugins;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class SpringBootVideApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootVideApplication.class, args);
}
}
Enable #ComponentScan({"com.plugins"}) , in Application
To access the properties defined in application.properties
myapp.url="xxxxxx"
in your class
#Value("${myapp.url}")
private String testValue;
but this cannot be a static variable, if it is a static variable you do some hack like this, by defining setter method
private static String testValue;
#Value("${myapp.url}")
public void testValue(String value) {
testValue = value;
}
I resolve this issue by addin #Autowired in the class which use the method of the other class this is a snippet
// Class: SearchContactController.java
#Autowired
ClassUtils cd;
#RequestMapping(value = "/ping")
public String pingRequest() {
return "Ping OK !" + cd.getTestValue();
}
I have a bean annoteded with JSR 303 annotations. I also added Spring aspect (#Around) for handling MethodConstraintViolationException. My problem is: if I execute methods with correct parameters - my aspect works (is executed - breakpoints added), but when I run methods with incorrect parameters then MethodConstraintViolationException is thrown and my aspect is not executed.
package noname.exception;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.hibernate.validator.method.MethodConstraintViolationException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.Ordered;
import noname.service.exceptions.ValidationException;
import noname.utils.ValidationExceptionProcessor;
#Aspect
public class ExceptionAspect implements Ordered {
#Autowired
private ValidationExceptionProcessor processor;
#Pointcut(value = "execution(* noname.conversionstrategy.api.IDocumentConverter.*(..))")
public void aopDocumentConverterPointcut() {
}
#Pointcut(value = "execution(* noname.service.api.IMailMerger.*(..))")
public void aopMailMargeServicePointcut() {
}
#SuppressWarnings("deprecation")
#Around("aopDocumentConverterPointcut() || aopMailMargeServicePointcut()")
public Object exceptionsAspect(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
try {
return proceedingJoinPoint.proceed();
} catch ( Throwable e ) {
if (e instanceof MethodConstraintViolationException) {
ValidationException exp = processor.process((MethodConstraintViolationException) e);
throw exp;
} else {
throw e;
}
}
}
#Override
public int getOrder() {
return Ordered.HIGHEST_PRECEDENCE;
}
}
Intefaces (IMailMerger and IDocumentConverter) are similar:
package noname.conversionstrategy.api;
import java.util.List;
import javax.validation.constraints.NotNull;
import org.springframework.validation.annotation.Validated;
import noname.service.domain.DocumentActionInput;
import noname.service.domain.DocumentActionResult;
import noname.validator.ValidActionInput;
#Validated
public interface IDocumentConverter {
DocumentActionResult convertDocument(#NotNull(message = "DocumentActionInput must be provided") #ValidActionInput DocumentActionInput document);
List<DocumentActionResult> convertDocuments(#NotNull(message = "DocumentActionInput must be provided") #ValidActionInput List<DocumentActionInput> documents);
}
I suppose spring execute first bean validation (it is probably executed with aspect too (?) ). If this validation throws MethodConstraintViolationException then my aspect is not executed, because spring aop doesn't support catching exceptions from anoother aspect (need confirmation).
I also created test with proxy (everything with my aspect looks fine):
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations = {"classpath:applicationContextTest.xml"})
public class ExceptionAspectSpringTest {
#Autowired
private IDocumentConverter documentConverter;
#Autowired
private ExceptionAspect exceptionAspect;
private IDocumentConverter proxy;
#Before
public void setUp() {
AspectJProxyFactory aspectJProxyFactory = new AspectJProxyFactory(documentConverter);
aspectJProxyFactory.addInterface(IDocumentConverter.class);
aspectJProxyFactory.addAspect(exceptionAspect);
proxy = aspectJProxyFactory.getProxy();
}
#Test( expected = ValidationException.class )
public void shouldThownValidationException() {
DocumentActionInput document = new DocumentActionInput();
proxy.convertDocument(document);
}
}
Any help appreciated