vendredi 22 février 2019

Test Service with Mockito, when Id is set by database

I have a function createObject() in my service rest Service:

@Service
public class MyService {

    //Repos and contructor

   @Transactional
   public ObjectDto createObject(Object) {

       Mother mother = new Mother(name, age);
       Kid kid = new Kid(name, age);

       mother.addKid(kid);

       this.motherRepo.saveAndFlush(mother); 

       Long motherId = mother.getId();

       doStuffWithMotherId();

       return new ObjectDto()
            .withMother(mother)
            .withKid(kid)
            .build();
  }
}

My entity for mother/kid is basically like this:

@Entity
@Table("mother")
public class mother() {

   @Id
   @GeneratedValue(strategy = GenerationType.IDENTITY)
   @Column(name="id)
   private Long id;

   //other attributes, including @OneToMany for Kid
   //Getter/Setter

}

There is a similar Entity for Kid.

As you can see, the id is set by the database. There is no setter for id in the entity. The constructor is without id as well.

Now I want to test my service. I mock my repos and want to verify, that my ObjectDto contains the values, like id.

@RunWith(MockitoJUnitRunner.class)
@SpringBootTest
public MyServiceTest {

    @Mock
    private MotherRepo motherRepo;

    @InjectMocks
    private MyService myService;

    @Test
    void createObjectTest() {

        ObjectDto expectedObjectDto = setup...;
        Object inputObject = setup...;

        assertThat.(this.myService.createObject(inputObject))
             .isEqualToComparingFieldByField(expectedObjectDto);

    }
}

The expected ObjectDto looks something like

{
   "motherId":1,
   "motherAge":40,
   "kidId":1
   ...
}

The problem is, that the id is set up by the database. Since there is no database and the repository is mock with Mockito, this value is always null. Even if I set my expectedObjectDto with null as id, I need the id in the "doStuffWithMotherId()" in the service. Atm I get a NullPointerException.

Is there a possibility to set the id, like with ReflectionTestUtils.setField()? In literature I read, that a service should always be tested using mocks. Is this correct or do I need a in-memory db like H2?

Thanks for the help.

Aucun commentaire:

Enregistrer un commentaire