Test metody dodawania elementu do bazy danych nie działa

Test metody dodawania elementu do bazy danych nie działa
R8
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 62
0

Witam,
mam prosty webservice z crudem który działa, ale problem jest z metodą testującą dodawanie nowego elementu. Nie wiem jak to ugryźć.

Moja metoda wygląda tak:

Kopiuj
 	public Optional<PersonDto> addPerson(PersonDto personDto) {
		Assert.notNull(personDto, "personDto can't be null");
		Person person = personRepository
				.save(modelMapper.map(personDto, Person.class));
		return Optional.of(modelMapper.map(person, PersonDto.class));
	}

A test wygląda tak:

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

Niestety przy tak napisanym kodzie pojawia się taki o to problem:

Kopiuj
java.lang.IllegalArgumentException: source cannot be null

	at org.modelmapper.internal.util.Assert.notNull(Assert.java:53)
	at org.modelmapper.ModelMapper.map(ModelMapper.java:370)
	at com.softwaremind.crew.people.service.PersonService.addPerson(PersonService.java:85)
	at com.softwaremind.crew.people.service.PersonServiceTest.shouldAddPersonToDatabase(PersonServiceTest.java:75)
	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)

jarekr000000
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: U krasnoludów - pod górą
  • Postów: 4714
2

Pewnie na górze masz żałosne @Mock PersonReporistory personRepository, a jego metoda save domyślnie zwraca null.

Przy okazji: Testowanie serwisów przy pomocy zamokowanych repozytoriów bazodanowych mówi tyle o ich działaniu co zdjęcia profilowe w serwisach randkowych o urodzie właścicieli/lek.
(Coś tam można wywnioskować, ale....)

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

Czemu żałosne? tak mam takie rozwiązanie wydawało mi się że jest to optymalne. Problem pojawił się jak wprowadziłam asercje w klasie serwisowej, model maper został wstrzyknięty jako bean w klasie konfiguracyjnej:

Klasa testowa na górze wygląda następująco:

Kopiuj
	private PersonService personService;
	private ModelMapper mapper;
	
	@Mock
	private PersonRepository personRepository;
	
	@Before
	public void initTest() {
		MockitoAnnotations.initMocks(this);
		mapper = new ModelMapper();
		personService = new PersonService(personRepository, this.mapper);

	}

	@Before
	public void initMockRepository() {
		Person person1 = new Person(1L, "jan", "mucha", "krakow", "email1@ont.com", "Programing", "Developer");
		Person person2 = new Person(1L, "Alicja", "Kowalska", "Warszawa", "email2@gmail.com", "Business", "Designer");
		Mockito.when(personRepository.findAll()).thenReturn(Arrays.asList(person1, person2));
	}
R8
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 62
0

Jak zmieniłam metodę dodawania na taką :

Kopiuj
public void addPerson(PersonDto personDto) {
		Assert.notNull(personDto);
		Assert.notNull(personDto.getFirstName());
		personRepository.save(modelMapper.map(personDto, Person.class));
	}

Ale szkoda bo chciałam wykorzystać mapowanie żeby cały kod był spójny a teraz połowa metod jest robiona z wykorzystaniem javy 8 a druga połowa z taka. Dodatkowo caly restcontroller poszedł do zmiany. Lipa

jarekr000000
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: U krasnoludów - pod górą
  • Postów: 4714
1

Żeby Ci to zadziałało to musiałbyć jeszcze dodać:
w tym stylu.
Mockito.when(personRepository.save(anyObj())).thenAnswer (inv ->invocation.getArgumentAt(0, Person.class));

(Sorry, pisze z pamięci i nie używam Mockito w normalnych projektach, więc mogą być jakieś błędy).

A **żałosne **odnosiło się do moim zdaniem niskiej skuteczności takich testów na Mockach.
Przetestujesz Mockito ,ale ono już ma naprawdę miliony testów popisanych. Tysiace programistów na całym świecie pisze codziennie nowe testy do mockito. Moim zdaniem nie warto się dokładać.

Poza tym zawsze mam watpliwości jak widzę coś w stylu:
Mockito.verify(personRepository, times(1)).save(person1);

Jeśli potrafię tak napisać tą metodę, że zapisze się w bazie bez wywoływania save.. to czy to jest faktycznie 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.