From normal testing to springframework testing (not springboot) - java

i am trying to lear how to use spring framework.
So far i am converting an old project to spring framework. The program does run but i am stuck in the injection for the test class and i can not solve the problem.
the test class code is:
#ExtendWith(SpringExtension.class)
#ContextConfiguration(classes = gui.JdbcAppConfig.class)
class DbConnectionPersonsTest {
#Autowired
private SourcePersonsInterface dbConnectionPersons;
SourcePersonsInterface db = new DbConnectionPersons();
ArrayList<Person> expectedPersons = new ArrayList<>();
DbConnectionPersonsTest() throws SQLException, ClassNotFoundException {
this.db.setDbConnectionPersons(DbConfiguration.dbTest, DbConfiguration.userTest, DbConfiguration.pswTest);
}
#Test
void checkGetPersonsList() throws SQLException {
ArrayList<Person> extractedPersons = db.getPersonsList();
expectedPersons.add(new Person(1, "abc", "asd", 2));
expectedPersons.add(new Person(2, "abc", "asd", 2));
// assertTrue(expectedPersons.get(0).equals(extractedPersons.get(0)));
assertEquals(expectedPersons.get(0).getName(), extractedPersons.get(0).getName());
assertEquals(expectedPersons.get(0).getSurname(), extractedPersons.get(0).getSurname());
assertEquals(expectedPersons.get(0).getNumber(), extractedPersons.get(0).getNumber());
assertEquals(expectedPersons.get(0).getStamps(), extractedPersons.get(0).getStamps());
// assertTrue(expectedPersons.get(1).equals(extractedPersons.get(1)));
assertEquals(expectedPersons.get(1).getName(), extractedPersons.get(1).getName());
assertEquals(expectedPersons.get(1).getSurname(), extractedPersons.get(1).getSurname());
assertEquals(expectedPersons.get(1).getNumber(), extractedPersons.get(1).getNumber());
assertEquals(expectedPersons.get(1).getStamps(), extractedPersons.get(1).getStamps());
}}
the #Autowired private SourcePersonsInterface dbConnectionPersons;
does return null pointer so is not possible to use it.
is there some tutorial on how to do this kind of conversion?
//////////////////////////////////////////////////////////////////////
I did find a solution and the test is workin, BUt i dont know if is a correct one. ill post the code:
#ExtendWith(SpringExtension.class)
#ContextConfiguration(classes = gui.JdbcAppConfig.class)
class DbConnectionPersonsTest {
SourcePersonsInterface db;
ArrayList<Person> expectedPersons = new ArrayList<>();
#Autowired
void setUp(SourcePersonsInterface dbConnectionPersons) throws SQLException, ClassNotFoundException {
this.db = dbConnectionPersons;
this.db.setDbConnectionPersons(DbConfiguration.dbTest, DbConfiguration.userTest, DbConfiguration.pswTest);
}
#Test
void checkGetPersonsList() throws SQLException {...

Related

AEM JUnit java.lang.NullPointerException

I need to create a Junit test for a class in an AEM project and I'm having NullPointerException problems:
I create the ClassTestImpl
#ExtendWith({AemContextExtension.class, MockitoExtension.class})
class TestImpl {
private final AemContext ctx = new AemContext();
#Mock
private Test test;
#Mock
private ModelFactory modelFactory;
#BeforeEach
void setUp() throws Exception {
ctx.addModelsForClasses(TestImpl.class);
ctx.load().json("/com/project/core/models/adobe/TestImplTest.json","/content");
lenient().when(modelFactory.getModelFromWrappedRequest(eq(ctx.request()),
any(Resource.class), eq(Test.class)))
.thenReturn(test);
}
#Test
void testGetText() {
final String expected = "textTEST";
ctx.currentResource("/content/text");
Test test = ctx.request().adaptTo(Test.class);
String actual = test.getText();
assertEquals(expected,actual);
}
and the json structure:
"text": {
"jcr:primaryType": "nt:unstructured",
"sling:resourceType": "project/components/core/title",
"text": "textTEST"
}
}
when i Run test i give that result:
#Test
void testGetText() {
final String expected = "titleTEST";
ctx.currentResource("/content/title");
Title title = ctx.request().adaptTo(Title.class);
-->String actual = title[NullPointerException].getText();<--
assertEquals(expected,actual);
}
It looks like your model is a null reference. You do try to mock it with MockitoExtension but that's largely superfluous, given that you're also using AemContextExtension and it's probably the cause of the issue.
Null pointers aside, this code doesn't even test anything. Everything is mocked, even the Test class which I understand to be the subject under test.
Also, the parameter you're passing to addModelsForClasses looks like the test class (TestImpl) rather than the class of the Sling Model Test.
Instead of relying on Mockito, let the AEM Mocks library set up all the underlying objects by itself and make sure the class you're testing is the real thing, rather than a mock.
#ExtendWith(AemContextExtension.class)
class TestImpl {
private final AemContext ctx = new AemContext();
#BeforeEach
void setUp() throws Exception {
ctx.addModelsForClasses(Test.class); // Give it the Sling Model
ctx.load().json("/com/project/core/models/adobe/TestImplTest.json","/content");
}
#Test
void testGetText() {
final String expected = "textTEST";
ctx.currentResource("/content/text");
Test test = ctx.request().adaptTo(Test.class); // It'll use the actual class, not a mock this way
String actual = test.getText();
assertEquals(expected,actual);
}
}
See
https://sling.apache.org/documentation/development/sling-mock.html#sling-models-1
https://wcm.io/testing/aem-mock/usage-content-loader-builder.html

initialise a service for mocking in java with mockito and junit 5

I'm trying to learn some integration testing whilst creating a project to make a game database, and have got a class that calls a service within it's methods
public DigitalGame findDigitalGameByTitleAndPlatform(DigitalGame digitalGame){
if(digitalGame == null){
return null;
}
return GamesJPAService.iDigitalGameRepository.findDigitalGameByTitleAndPlatform(digitalGame.getTitle(), digitalGame.getPlatform());
}
The GamesJpaService as shown below, is initialised as an #Service when the project is started as an application. But is not initialised within the test class, no matter whether it is autowired,newed up, or any other method I have spotted to try and initialise it. for example using the #InjectMocks annotation
#Service
public class GamesJPAService implements IJpaServices {
public static IDigitalGameRepository iDigitalGameRepository;
#Autowired
private IDigitalGameRepository iDigitalGameRepo;
#PostConstruct
public void init(){
iDigitalGameRepository = this.iDigitalGameRepo;
}
}
The IDigitalGameRepository that it calls looks like:
public interface IDigitalGameRepository extends JpaRepository<DigitalGame, String> {
DigitalGame findDigitalGameByTitleAndPlatform(String title, Platform platform);
}
I have ommited some methods from the proceeding code. My test class also looks like (at the moment)
#DisplayName("Digital Games Dao Test")
class DigitalGamesDaoTest {
Set<Peripheral> compatiblePeriphs = new HashSet<>();
Set<SupportedLanguages> supportedLanguages = new HashSet<>();
List<Mods> mods = new ArrayList<>();
List<DLC> dlc = new ArrayList<>();
DigitalGame olliolli = new DigitalGame("olliolli", "", "sports", "olliolli", new ReleaseDate(), new Platform(), compatiblePeriphs, new Developer(), new Publisher(), new Region(), supportedLanguages, new NoneEnglish(), mods, dlc, "", new SpecialEdition(), true, new Platform());
private IDigitalGamesDao digitalGamesDao;
#Mock
GamesJPAService gamesJpaService;
#BeforeEach
void setUp() {
digitalGamesDao = new DigitalGamesDao();
}
#Test
#DisplayName("insertDigitalGame should return false when digital game already in database")
public void insertDigitalGameShouldReturnFalseWhenDigitalGameInDatabase(){
EntityManager mockEntityManager = mock(EntityManager.class);
when(GamesJPAService.iDigitalGameRepository.findDigitalGameByTitleAndPlatform(olliolli.getTitle(), olliolli.getPlatform())).thenReturn(olliolli);
doReturn(olliolli).when(digitalGamesDao.findDigitalGameByTitleAndPlatform(olliolli));
when(digitalGamesDao.findDigitalGameByTitleAndPlatform(olliolli)).thenReturn(olliolli);
when(mockEntityManager.merge(olliolli)).thenReturn(null);
assertFalse(digitalGamesDao.insertDigitalGame(olliolli));
}
#Test
#DisplayName("insertDigitalGame should return true when digital game added to database")
public void insertDigitalGameShouldReturnTrueWhenDigitalGameNotInDatabase(){
}
and I am getting a null pointer exception,
java.lang.NullPointerException: Cannot invoke "com.me.gamedatabasebackend.dao.gamesJPA.IDigitalGameRepository.findDigitalGameByTitleAndPlatform(String, com.me.gamedatabasebackend.model.platform.Platform)" because "com.me.gamedatabasebackend.dao.gamesJPA.GamesJPAService.iDigitalGameRepository" is null
As GamesJPAService is not being tested I need to know how to skip it and just return the value. So I need help to find a way for either, doing a component scan from my test class, or importing the GamesJPAService into it in a useable manner.
You need to annotate your test class with some think like that to make injection works
#ExtendWith(SpringExtension.class)
#ContextConfiguration(classes = { SpringTestConfiguration.class })
DisplayName("Digital Games Dao Test")
class DigitalGamesDaoTest {
...
But you have a nullpointer because GamesJPAService.iDigitalGameRepository is null. That's a static property and the instance of GamesJPAService is a mock so the init() method is never call.

Getting NullPointerException while mocking in SpringBoot

Am trying to write a Junit Test case for one of the class. But getting error while trying to do it,
Test class looks like below -
public class IntegratorClassTest{
#InjectMocks
IntegratorClass integratorClass;
#Mock
RequestClass requestClass;
#Mock
ContentList contentResponse;
#Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
}
#Test
public void getCmsOffersTest()throws Exception{
ContentService contentService = Mockito.mock(ContentService.class);
RequestClass requestClass = Mockito.mock(RequestClass.class);
ContentList contentResponse = getContentList();
when(contentService.getContentCollection()).thenReturn(contentResponse);
Validator validator = Mockito.mock(Validator.class);
List<OfferDetails> offerList = new ArrayList<OfferDetails>();
Mockito.doNothing().when(validator).validateData(offerList);
List<OfferDetails> offerListResult = integratorClass.getCmsOffers(contentService, requestClass);
assertTrue(offerListResult.size()>0);
}
}
And the implementation class looks something like below -
public class IntegratorClass {
private static final Logger LOGGER = LoggerFactory.getLogger(IntegratorClass.class);
#Autowired
Validator validator;
public List<OfferDetails> getCmsOffers(ContentService contentService,RequestClass requestClass)throws Exception{
LOGGER.info("Entered method getCmsOffers to get the list of offers from CMS");
List<OfferDetails> offerList = new ArrayList<OfferDetails>();
ContentList contentResponse = null;
try
{
contentResponse = contentService.getContentCollection();
offerList = getOfferListFromCmsResponse(contentResponse, requestClass);
LOGGER.info("Total number of active offers we got from CMS are -" + offerList.size());
}catch (Exception e)
{
ErrorResponse errorResponse = PromotionalOffersUtilities.createErrorResponse("500", e.getMessage(),"Getting error while fetching content from CMS - getCmsOffers", ErrorResponse.Type.ERROR);
LOGGER.error("Getting error while fetching content from CMS with Error Message: " + e.getMessage());
throw new ServiceException(errorResponse, HttpStatus.INTERNAL_SERVER_ERROR);
}
//failing here
validator.validateData(offerList);
LOGGER.info("Exiting method getCmsOffers");
return offerList;
}
}
When I ran it in debug mode am error for the line validator.validateData(offerList);.
It is returning "NullPointerException".
You need to include the Validator when mocking dependencies so that it will be injected into the subject under test
#Mock
Validator validator;
Also when arranging the behavior of the validator use an argument matcher for the invoked member as the current setup wont match because they will be comparing different instances when exercising the test.
Mockito.doNothing().when(validator).validateData(any(List<OfferDetails>.class));
You are manually mocking the other dependencies within the test method so they are not needed out side of that
The test now becomes
public class IntegratorClassTest{
#InjectMocks
IntegratorClass integratorClass;
#Mock
Validator validator;
#Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
}
#Test
public void getCmsOffersTest()throws Exception{
//Arrange
ContentService contentService = Mockito.mock(ContentService.class);
RequestClass requestClass = Mockito.mock(RequestClass.class);
ContentList contentResponse = getContentList();
Mockito.when(contentService.getContentCollection()).thenReturn(contentResponse);
Mockito.doNothing().when(validator).validateData(any(List<OfferDetails>.class));
//Act
List<OfferDetails> offerListResult = integratorClass.getCmsOffers(contentService, requestClass);
//Assert
assertTrue(offerListResult.size() > 0);
}
}

mocking a constructor to see if it throws an exception

Java 8
I have the following constructor I want to test using Mockito.
I want the test to throw an exception if a null is passed for the repository.
public PresenterImp(#Nonnull IRepository repository, IScheduler scheduler) {
super(schedulerFactory);
this.repository = Preconditions.checkNotNull(repository);
}
What would be the best way to do this? As my presenter is not a mock so I can’t use a when..
In my setup I do the following:
#Before
public void setup() throws Exception {
repository = Mockito.mock(IRepository.class);
iScheduler = Mockito.mock(IScheduler.class);
viewContract = Mockito.mock(ViewContract.class);
presenter = new PresenterImp(repository, iScheduler);
optInNotificationPresenter.attachView(viewContract);
}
Many thanks for any suggestions
Can do it as:
#Test(expected=NullPointerException.class )
public void testNullCheck() throws Exception
new PresenterImp(null, mock);
}

Cannot inject service into Spring test

financialReportService is null in REST controller that denotes it fails to inject.
Test:
#RunWith(SpringRunner.class)
#SpringBootTest(classes = SnapshotfindocApp.class)
public class FindocResourceIntTest {
#Inject
private FinancialReportService financialReportService;
#Before
public void setup() {
MockitoAnnotations.initMocks(this);
FindocResource findocResource = new FindocResource();
ReflectionTestUtils.setField(findocResource, "findocRepository", findocRepository);
this.restFindocMockMvc = MockMvcBuilders.standaloneSetup(findocResource)
.setCustomArgumentResolvers(pageableArgumentResolver)
.setMessageConverters(jacksonMessageConverter).build();
}
#Test
#Transactional
public void getFinancialRecords() throws Exception {
// Get all the financial-reports
restFindocMockMvc.perform(get("/api/financial-reports"))
.andExpect(status().isOk());
List<Findoc> finReports = financialReportService.getFinancialReports();
for (Findoc fr : finReports) {
assertThat(fr.getNo_months()).isBetween(12, 18);
LocalDate documentTimeSpanLimit = LocalDate.now().minusMonths(18);
assertThat(fr.getFinancial_date()).isAfterOrEqualTo(documentTimeSpanLimit);
}
}
The service:
#Service
#Transactional
public class FinancialReportService {
private final Logger log = LoggerFactory.getLogger(FinancialReportService.class);
#Inject
private FinancialReportDAO financialReportDAO;
public List<Findoc> getFinancialReports(){
return financialReportDAO.getFinancialReports();
}
}
Controller:
#GetMapping("/financial-reports")
#Timed
public List<Findoc> getFinancialReports() {
log.debug("REST request to get financial records");
return financialReportService.getFinancialReports(); // financialReportService is null
}
Update:
The application is generated by JHipster. Then the new service and DAO files were added to enable custom database queries to H2.
After #Injecting the service, you also need to set the field in the setup() method. Adding the below line should solve your problem
ReflectionTestUtils.setField(findocResource, "financialReportService", financialReportService);
On a separate note, the following part of the test looks weird. You are fetching the financial reports twice. This file is the FindocResourceIntTest, so I would remove any direct calls to financialReportService.
// Get all the financial-reports
restFindocMockMvc.perform(get("/api/financial-reports"))
.andExpect(status().isOk());
List<Findoc> finReports = financialReportService.getFinancialReports();

Categories