簡體   English   中英

單元測試如何使用 Mockito 模擬存儲庫

[英]Unit Tests How to Mock Repository Using Mockito

我在存根我的存儲庫時遇到問題。 有人建議我創建另一個 application.properties(我還沒有這樣做)並使用像 H2 這樣的內存數據庫。 我想知道我是否可以只存根調用,以便當 myDataService.findById(id) 被調用而不是嘗試從數據庫中獲取時,只能返回一個模擬對象?

我是為我的單元測試和 Spring Boot 編寫模擬的新手,所以也許我錯過了一些東西。 下面的代碼(試圖簡化並使名稱通用以在此處發布)。

我的測試班

public class MyServiceImplTest 
{
    private MyDataService myDataService;
    private NyService myService;
    private MyRepository myRepository;

    @Before
    public void setUp() {
        myDataService = Mockito.mock(MyDataServiceImpl.class);
        myService = new MyServiceImpl(myDataService);
    }

    @Test
    public void getById_ValidId() {
        doReturn(MyMockData.getMyObject()).when(myDataService).findById("1");
        when(myService.getById("1")).thenReturn(MyMockData.getMyObject());
        MyObject myObject = myService.getById("1");

        //Whatever asserts need to be done on the object myObject 
    }
}

用於對數據層進行服務調用的類

@Service
public class MyServiceImpl implements MyService {
    MyDataService myDataService;

    @Autowired
    public MyServiceImpl(MyDataService myDataService) {
        this.myDataService = myDataService;
    }

    @Override
    public MyObject getById(String id) {
        if(id == null || id == "") {
            throw new InvalidRequestException("Invalid Identifier");
        }

        MyObject myObj;
        try {
            myObj = myDataService.findById(id);
        }catch(Exception ex) {
            throw new SystemException("Internal Server Error");
        }

        return myObj;
    }
}

這是我在測試中遇到問題的地方。 當調用 findById() 方法時,變量存儲庫為空,因此在嘗試執行 repository.findOne(id) 時它會拋出異常。 這就是我試圖模擬的內容,但是存儲庫給了我問題。

@Repository
@Qualifier("MyRepo")
public class MyDataServiceImpl {

    @PersistenceContext
    private EntityManager em;

    private MyRepository repository;

    @Autowired
    public MyDataServiceImpl(MyRepository repository) {
        super(repository);
        this.repository = repository;
    }

    public MyObject findById(String id) {
        P persitentObject = repository.findOne(id);
        //Calls to map what persitentObject holds to MyObject and returns a MyObject 
    }
}

此處 MyRepository 的代碼只是為了顯示它是一個擴展 CrudRepository 的空接口

public interface MyRepository extends CrudRepository<MyObjectPO, String>, JpaSpecificationExecutor<MyObjectPO> {

}

首先讓我說您使用構造函數注入而不是字段注入(這使得使用模擬編寫測試變得更加簡單)走在正確的軌道上。

public class MyServiceImplTest 
{
    private MyDataService myDataService;
    private NyService myService;

    @Mock
    private MyRepository myRepository;

    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this); // this is needed for inititalizytion of mocks, if you use @Mock 
        myDataService = new MyDataServiceImpl(myRepository);
        myService = new MyServiceImpl(myDataService);
    }

    @Test
    public void getById_ValidId() {

        doReturn(someMockData).when(myRepository).findOne("1");
        MyObject myObject = myService.getById("1");

        //Whatever asserts need to be done on the object myObject 
    }
}

該調用一直從您的服務 --> dataService 開始。 但只有你的存儲庫調用被模擬。
通過這種方式,您可以控制和測試類的所有其他部分(服務和數據服務)並僅模擬存儲庫調用。

暫無
暫無

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

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