簡體   English   中英

由數據庫設置ID時,使用Mockito進行測試服務

[英]Test Service with Mockito, when Id is set by database

我的服務休息服務中有一個函數createObject():

@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 kidId = kid.getId();

       doStuffWithKidId();

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

我的母親/孩子實體基本上是這樣的:

@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

}

有一個類似於Kid的實體。

如您所見,該ID由數據庫設置。 實體中沒有ID的設置器。 構造函數也沒有ID。

現在,我要測試我的服務。 我模擬了我的倉庫,並想驗證我的ObjectDto是否包含值,例如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);

    }
}

預期的ObjectDto看起來像

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

問題是,該ID由數據庫設置。 由於沒有數據庫,並且使用Mockito模擬了存儲庫,因此該值始終為null。 即使將我的ExpectedObjectDto設置為null作為id,我也需要服務中“ doStuffWithKidId()”中的id。 Atm我收到NullPointerException。

是否可以設置id,例如ReflectionTestUtils.setField()? 在我讀過的文獻中,應該始終使用模擬對服務進行測試。 這是正確的還是我需要像H2這樣的內存數據庫?

謝謝您的幫助。

使用doAnswer ...

import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.test.util.ReflectionTestUtils;

import static org.assertj.core.api.Java6Assertions.assertThat;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;

@RunWith(MockitoJUnitRunner.class)
public class MockitoSettingDatabaseIds {

    private static class TestEntity {
        private long id;
        private String text;

        public TestEntity(String text) {
            this.text = text;
        }

        public long getId() {
            return id;
        }

        public String getText() {
            return text;
        }
    }

    private interface TestEntityDAO {
        void save(TestEntity entity);
    }

    private static long someLogicToTest(TestEntityDAO dao, TestEntity entity) {
        dao.save(entity);
        return entity.getId();
    }

    @Test
    public void shouldReturnDatabaseGeneratedId() {
        long expectedId = 12345L;

        TestEntityDAO dao = mock(TestEntityDAO.class);
        TestEntity entity = new TestEntity("[MESSAGE]");

        doAnswer(invocation -> {
            ReflectionTestUtils.setField((TestEntity) invocation.getArgument(0), "id", expectedId);
            return null;
        }).when(dao).save(entity);

        assertThat(someLogicToTest(dao, entity)).isEqualTo(expectedId);
    }
}

要回答您的評論,請對Kid系列做同樣的事情,例如...

        doAnswer(invocation -> {
            Mother toSave = (Mother) invocation.getArgument(0);
            ReflectionTestUtils.setField(toSave, "id", expectedId);

            for (int k = 0; k < toSave.getKids().size(); k++) {
                ReflectionTestUtils.setField(toSave.getKids().get(k), "id", expectedId + k + 1);
            }

            return null;
        }).when(dao).save(entity);

這將設置id的的MotherexpectedId和的的ID Kid s至expectedId + 1expectedId + 2等。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM