NullPointerException podczas tesowania metody

NullPointerException podczas tesowania metody
R8
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 62
0

Witam,
podczas testowania metody pojawia mi się wyżej wymieniony problem.
To jest mój test:

Kopiuj
	@Test
	public void shouldAddPersonToDatabase() {
		Person person1 = new Person(1L, "jan", "mucha", "krakow", "email1@onet.com", "Programing", "Developer");
		personService.createPerson(mapper.map(person1, PersonDto.class));
		Mockito.verify(personRepository, times(1)).save(person1);
	}

A to jest metoda:

Kopiuj
	@Transactional
	public void createPerson(PersonDto personDto) {
		if (Optional.ofNullable(personDto).isPresent()) {
			personRepository.save(modelMapper.map(personDto, Person.class));
		} else {
			throw new IllegalArgumentException("insert correct argument");
		}
	}
fasadin
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 4883
0

a nie mozesz postawic po prostu breakpointa na poczatku metody i zobaczyc ktory argument jest nullem?

baant
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Wrocław
  • Postów: 524
0
Kopiuj
  if (Optional.ofNullable(personDto).isPresent()) {

nie łatwiej tak:

Kopiuj
 if(personDto != null)

? xd

R8
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 62
0

baaant dzięki poprawione. Nie wiem czemu tak tam było.
fasadin ten test nawet nie rusza nie mam jak wstawić brakpointa bo jak daje nawet na początku to pojawia się ten nullPointer

baant
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Wrocław
  • Postów: 524
0

Wklej ten NullPointerException tutaj, bo nawet nie wiadomo gdzie leci z Twojego opisu

R8
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 62
0

zwróciło mi mapper = null

R8
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 62
0
Kopiuj
java.lang.NullPointerException
	at com.softwaremind.crew.people.service.PersonServiceTest.shouldAddPersonToDatabase(PersonServiceTest.java:74)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
	at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
	at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
	at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
	at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
	at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
	at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
baant
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Wrocław
  • Postów: 524
0

Daj breakpoint przy personService i odpal ten test ale klikaj Debug zamiast Run. Przechodząc kolejne kroki dowiesz się dokładnie gdzie i czemu leci Ci NPE

baant
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Wrocław
  • Postów: 524
0

Testujesz zamockowane repo i pytasz czy "cannot find local variable" to może być błąd.
Nie opuściłaś kilka pierwszych zajęć przypadkiem? :)

R8
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 62
0

Z tym mockowaniem obiektów i testowaniem to dla mnie właśnie czarna magia :) Stąd tyle problemów :/ co jakiś opis to inaczej wytłumaczone :/ Oczywiście cały crud działa w postmanie a testy nie. Czyli to jest ten błąd ?:)
Ale zaraz zaraz ja mam repo zamockowane w klasie :
@mock
private PersonRepository personRepository;

baant
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Wrocław
  • Postów: 524
0

Pokaż cały kod serwisu, repo i testu, bo nie chce mi się wróżyć z fusów.
A ten @mock w klasie serwisowej to chyba miał być @Autowired czy inny @Inject? Mocki używa się w testach a nie normalnych klasach

R8
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 62
0

To jest kod serwisu

Kopiuj
@Service
public class PersonService {
	
	private final PersonRepository personRepository;
	private final ModelMapper modelMapper;
	
	@Autowired
	public PersonService(PersonRepository personRepository) {
		this.personRepository = personRepository;
		this.modelMapper = new ModelMapper();
	}

@Transactional
	public void createPerson(PersonDto personDto) {
		if (personDto != null) {
			personRepository.save(modelMapper.map(personDto, Person.class));
		} else {
			throw new IllegalArgumentException("insert correct argument");
		}
	}

To jest kod Controllera:

Kopiuj
@PostMapping("/persons")
	public ResponseEntity<PersonDto> createPerson(@RequestBody PersonDto personDto) {
		try {
			personService.createPerson(personDto);
			return ResponseEntity.ok(personDto);
		} catch (Exception e) {
			return ResponseEntity.badRequest().build();
		}
	}

To jest repo:

Kopiuj
@Repository
public interface PersonRepository extends JpaRepository<Person, Long> {
	
}

A to jest niedziałający test:

Kopiuj
	@Test
	public void shouldAddPersonToDatabase() {
		Person person1 = new Person(1L, "jan", "mucha", "krakow", "email1@onet.com", "Programing", "Developer");
		personService.createPerson(mapper.map(person1, PersonDto.class));
		Mockito.verify(personRepository, times(1)).save(person1);
	}
R8
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 62
0
Kopiuj
public class PersonServiceTest {
	
	private PersonService personService;
	private ModelMapper mapper;
	
	@Mock
	private PersonRepository personRepository;
	
	@Before
	public void initTest() {
		MockitoAnnotations.initMocks(this);
		personService = new PersonService(personRepository);
	}
	
	@Before
	public void initMockRepository() {
		Person person1 = new Person(1L, "jan", "mucha", "krakow", "email1@onet.com", "Programing", "Developer");
		Person person2 = new Person(3L, "Alicja", "Kowalska", "Warszawa", "email2@gmail.com", "Business", "Designer");
		Mockito.when(personRepository.findAll()).thenReturn(Arrays.asList(person1, person2));
	}

Proszę z debuggerem walczę.

baant
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Wrocław
  • Postów: 524
1

Odwołujesz się w teście do mappera, który nie jest zainicjalizowany nigdzie(przynajmniej tutaj tego nie widać). Tworzysz ModelMapper w serwisie ale to nie jest ten sam obiekt, którego używasz w teście

R8
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 62
0

Dziękuje bardzo złoty człowieku!! :) Już modelmapper zainicializowany. Dziekuje jeszcze raz wszystko już działa. Jedyne czeko nie rozumiem to :) "Testujesz zamockowane repo i pytasz czy "cannot find local variable" to może być błąd."

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.