Skip to content

Commit

Permalink
Fix @mock annotation support (#270)
Browse files Browse the repository at this point in the history
* Add mockito-junit-jupiter package to support @ExtendWith(MockitoExtension.class)

* Add tests for mocks with annotations

* Fix bug in @mock

* Fix issue with generics
  • Loading branch information
martinmladenov authored May 8, 2024
1 parent 9e1eed9 commit 6eb1299
Show file tree
Hide file tree
Showing 6 changed files with 297 additions and 2 deletions.
7 changes: 7 additions & 0 deletions andy/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,13 @@
<version>${mockito.version}</version>
</dependency>

<!-- https://mvnrepository.com/artifact/org.mockito/mockito-junit-jupiter -->
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
<version>${mockito.version}</version>
</dependency>

<!-- org.objenesis.objenesis is needed for Mockito to work correctly with Pitest -->
<!-- https://mvnrepository.com/artifact/org.objenesis/objenesis -->
<dependency>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,9 @@ public boolean visit(FieldDeclaration fd) {

// If the field is annotated with @Mock, check if it's the class we are interested in
if (hasMockAnnotation) {
String className = fd.getType().toString();
classWasMocked = className.contains(classToBeMocked);
String className = fd.getType().resolveBinding().getBinaryName();
String simpleName = className.substring(className.lastIndexOf('.') + 1);
classWasMocked = simpleName.equals(classToBeMocked);
}
}
return super.visit(fd);
Expand Down
11 changes: 11 additions & 0 deletions andy/src/test/java/integration/CodeChecksTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,17 @@ void allChecksPass() {
.has(codeCheck("getTripById should be set up", true, 1));
}

@Test
void mockChecksWithAnnotationPass() {
Result result = run( "SoftWhereLibrary", "SoftWhereTestsWithAnnotation", "SoftWhereConfigWithCodeChecksConfiguration");

assertThat(result)
.has(checksScore(3,3))
.has(codeCheck("Trip Repository should be mocked", true, 1))
.has(codeCheck("Trip should not be mocked", true, 1))
.has(codeCheck("getTripById should be set up", true, 1));
}

@Test
void someChecksFail() {
Result result = run( "SoftWhereLibrary", "SoftWhereTests", "SoftWhereConfigWithCodeChecks2Configuration");
Expand Down
18 changes: 18 additions & 0 deletions andy/src/test/java/integration/JUnitTestsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,24 @@ void mocksWork() {
assertThat(result.getTests().hasTestsFailingOrFailures()).isFalse();
}

@Test
void mocksWithAnnotationWork() {
Result result = run(Action.TESTS, "SoftWhereLibrary", "SoftWhereTestsWithAnnotation");

assertThat(result.getTests().getTestsSucceeded()).isEqualTo(3);
assertThat(result.getTests().getTestsRan()).isEqualTo(3);
assertThat(result.getTests().hasTestsFailingOrFailures()).isFalse();
}

@Test
void mocksWithAnnotationExtendWithWork() {
Result result = run(Action.TESTS, "SoftWhereLibrary", "SoftWhereTestsWithAnnotationExtendWith");

assertThat(result.getTests().getTestsSucceeded()).isEqualTo(3);
assertThat(result.getTests().getTestsRan()).isEqualTo(3);
assertThat(result.getTests().hasTestsFailingOrFailures()).isFalse();
}

}


Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
package delft;

import static org.assertj.core.api.Assertions.*;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.ArgumentMatchers.*;
import static org.mockito.Mockito.*;

import java.time.LocalDate;
import java.util.*;
import java.util.stream.*;
import org.junit.jupiter.api.*;
import org.mockito.*;


class SoftWhereTests {

//Methods have setup inside them, since I cannot use @BeforeEach and am
//not sure if if I write a separate method to setup this will work, so yeah
//there is a ton of code duplication to make sure grading will
//work as expected. I also need to not have any dependency between tests,
//so I cannot depend on one test making the setup. I will also not risk
//putting setup into lines 26-32 without a method because I have no clue
//what your grading system does and if it would work.
//I have just chosen the safest way.

@Mock
ReservationRepository reservationRepository;

@Mock
TripRepository tripRepository;

SoftWhere softwhere;
Person person1, person2, person3, person4, person5, person6;

Trip trip1, trip2, trip3;
Info info1, info2, info3;

Reservation res1, res2, res3, res4;

//test when it is possible to register for the given trip
@Test
void testPossibleToRegister() {
MockitoAnnotations.openMocks(this);


softwhere = new SoftWhere(tripRepository, reservationRepository);

person1 = new Person("fname1", "mname1", "lname1", LocalDate.of(1998, 2, 5));
person4 = new Person("fname4", "mname4", "lname4", LocalDate.of(1995, 11, 17));
person5 = new Person("fname5", "mname5", "lname5", LocalDate.of(1978, 1, 1));
info2 = new Info(LocalDate.of(2021, 7, 1), LocalDate.of(2021, 7, 15), Destination.MALTA);
trip2 = new Trip("Trip to Malta", info2, 2050, 3);
res4 = new Reservation(trip2, new ArrayList<>(List.of(person4, person5)));

when(tripRepository.getTripById(2L)).thenReturn(trip2);
when(reservationRepository.getAllReservationsByTrip(trip2)).thenReturn(new ArrayList<>(List.of(res4)));

List<Person> people = new ArrayList<>(List.of(person1));

assertTrue(softwhere.makeReservation(2L, people));

verify(tripRepository, times(1)).getTripById(2L);
verify(reservationRepository, times(1)).getAllReservationsByTrip(trip2);
verify(reservationRepository, times(1)).save(new Reservation(trip2, people));

verifyNoMoreInteractions(tripRepository);
verifyNoMoreInteractions(reservationRepository);
}

//test when it is impossible to make a reservation
//as there are not enough places left
@Test
void testNotEnoughPlacesLeft() {
reservationRepository = mock(ReservationRepository.class);
tripRepository = mock(TripRepository.class);

softwhere = new SoftWhere(tripRepository, reservationRepository);

person3 = new Person("fname3", "mname3", "lname3", LocalDate.of(1998, 11, 17));
person4 = new Person("fname4", "mname4", "lname4", LocalDate.of(1995, 11, 17));

person1 = new Person("fname1", "mname1", "lname1", LocalDate.of(1998, 2, 5));
person2 = new Person("fname2", "mname2", "lname2", LocalDate.of(2001, 4, 3));
person5 = new Person("fname5", "mname5", "lname5", LocalDate.of(1978, 1, 1));
person6 = new Person("fname6", "mname6", "lname6", LocalDate.of(2004, 10, 4));
info1 = new Info(LocalDate.of(2021, 6, 24), LocalDate.of(2021, 6, 30), Destination.GREECE);
trip1 = new Trip("Trip to Greece", info1, 1999, 5);
res1 = new Reservation(trip1, new ArrayList<>(List.of(person1, person2)));
res2 = new Reservation(trip1, new ArrayList<>(List.of(person5, person6)));

when(tripRepository.getTripById(1L)).thenReturn(trip1);
when(reservationRepository.getAllReservationsByTrip(trip1)).thenReturn(new ArrayList<>(List.of(res1, res2)));

List<Person> people = new ArrayList<>(List.of(person3, person4));

assertFalse(softwhere.makeReservation(1L, people));

verify(tripRepository, times(1)).getTripById(1L);
verify(reservationRepository, times(1)).getAllReservationsByTrip(trip1);

verifyNoMoreInteractions(tripRepository);
verifyNoMoreInteractions(reservationRepository);
}

//test when the wanted trip does not exist
@Test
void testNonexistentTrip() {
reservationRepository = mock(ReservationRepository.class);
tripRepository = mock(TripRepository.class);

softwhere = new SoftWhere(tripRepository, reservationRepository);

person3 = new Person("fname3", "mname3", "lname3", LocalDate.of(1998, 11, 17));

when(tripRepository.getTripById(4L)).thenThrow(new ElementNotFoundException());

List<Person> people = new ArrayList<>(List.of(person3));

assertFalse(softwhere.makeReservation(4L, people));

verify(tripRepository, times(1)).getTripById(4L);

verifyNoMoreInteractions(tripRepository);
verifyNoMoreInteractions(reservationRepository);
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
package delft;

import static org.assertj.core.api.Assertions.*;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.ArgumentMatchers.*;
import static org.mockito.Mockito.*;

import java.time.LocalDate;
import java.util.*;
import java.util.stream.*;
import org.junit.jupiter.api.*;
import org.mockito.*;

import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.junit.jupiter.MockitoExtension;


@ExtendWith(MockitoExtension.class)
class SoftWhereTests {

//Methods have setup inside them, since I cannot use @BeforeEach and am
//not sure if if I write a separate method to setup this will work, so yeah
//there is a ton of code duplication to make sure grading will
//work as expected. I also need to not have any dependency between tests,
//so I cannot depend on one test making the setup. I will also not risk
//putting setup into lines 26-32 without a method because I have no clue
//what your grading system does and if it would work.
//I have just chosen the safest way.

@Mock
ReservationRepository reservationRepository;

@Mock
TripRepository tripRepository;

SoftWhere softwhere;
Person person1, person2, person3, person4, person5, person6;

Trip trip1, trip2, trip3;
Info info1, info2, info3;

Reservation res1, res2, res3, res4;

//test when it is possible to register for the given trip
@Test
void testPossibleToRegister() {
MockitoAnnotations.openMocks(this);


softwhere = new SoftWhere(tripRepository, reservationRepository);

person1 = new Person("fname1", "mname1", "lname1", LocalDate.of(1998, 2, 5));
person4 = new Person("fname4", "mname4", "lname4", LocalDate.of(1995, 11, 17));
person5 = new Person("fname5", "mname5", "lname5", LocalDate.of(1978, 1, 1));
info2 = new Info(LocalDate.of(2021, 7, 1), LocalDate.of(2021, 7, 15), Destination.MALTA);
trip2 = new Trip("Trip to Malta", info2, 2050, 3);
res4 = new Reservation(trip2, new ArrayList<>(List.of(person4, person5)));

when(tripRepository.getTripById(2L)).thenReturn(trip2);
when(reservationRepository.getAllReservationsByTrip(trip2)).thenReturn(new ArrayList<>(List.of(res4)));

List<Person> people = new ArrayList<>(List.of(person1));

assertTrue(softwhere.makeReservation(2L, people));

verify(tripRepository, times(1)).getTripById(2L);
verify(reservationRepository, times(1)).getAllReservationsByTrip(trip2);
verify(reservationRepository, times(1)).save(new Reservation(trip2, people));

verifyNoMoreInteractions(tripRepository);
verifyNoMoreInteractions(reservationRepository);
}

//test when it is impossible to make a reservation
//as there are not enough places left
@Test
void testNotEnoughPlacesLeft() {
reservationRepository = mock(ReservationRepository.class);
tripRepository = mock(TripRepository.class);

softwhere = new SoftWhere(tripRepository, reservationRepository);

person3 = new Person("fname3", "mname3", "lname3", LocalDate.of(1998, 11, 17));
person4 = new Person("fname4", "mname4", "lname4", LocalDate.of(1995, 11, 17));

person1 = new Person("fname1", "mname1", "lname1", LocalDate.of(1998, 2, 5));
person2 = new Person("fname2", "mname2", "lname2", LocalDate.of(2001, 4, 3));
person5 = new Person("fname5", "mname5", "lname5", LocalDate.of(1978, 1, 1));
person6 = new Person("fname6", "mname6", "lname6", LocalDate.of(2004, 10, 4));
info1 = new Info(LocalDate.of(2021, 6, 24), LocalDate.of(2021, 6, 30), Destination.GREECE);
trip1 = new Trip("Trip to Greece", info1, 1999, 5);
res1 = new Reservation(trip1, new ArrayList<>(List.of(person1, person2)));
res2 = new Reservation(trip1, new ArrayList<>(List.of(person5, person6)));

when(tripRepository.getTripById(1L)).thenReturn(trip1);
when(reservationRepository.getAllReservationsByTrip(trip1)).thenReturn(new ArrayList<>(List.of(res1, res2)));

List<Person> people = new ArrayList<>(List.of(person3, person4));

assertFalse(softwhere.makeReservation(1L, people));

verify(tripRepository, times(1)).getTripById(1L);
verify(reservationRepository, times(1)).getAllReservationsByTrip(trip1);

verifyNoMoreInteractions(tripRepository);
verifyNoMoreInteractions(reservationRepository);
}

//test when the wanted trip does not exist
@Test
void testNonexistentTrip() {
reservationRepository = mock(ReservationRepository.class);
tripRepository = mock(TripRepository.class);

softwhere = new SoftWhere(tripRepository, reservationRepository);

person3 = new Person("fname3", "mname3", "lname3", LocalDate.of(1998, 11, 17));

when(tripRepository.getTripById(4L)).thenThrow(new ElementNotFoundException());

List<Person> people = new ArrayList<>(List.of(person3));

assertFalse(softwhere.makeReservation(4L, people));

verify(tripRepository, times(1)).getTripById(4L);

verifyNoMoreInteractions(tripRepository);
verifyNoMoreInteractions(reservationRepository);
}
}

0 comments on commit 6eb1299

Please sign in to comment.