本文介紹了單元測試如何使用Mockito模擬存儲庫的處理方法,對大家解決問題具有一定的參考價值,需要的朋友們下面隨著小編來一起學習吧!
問題描述
我在清除存儲庫時遇到問題。有人建議我只創(chuàng)建另一個Applation.Properties(我還沒有這樣做),并使用像h2這樣的內存數(shù)據(jù)庫。不過,我想知道是否可以只將調用存根,這樣在調用myDataService.findById(Id)時,而不是試圖從數(shù)據(jù)庫中獲取時,只會返回一個模擬對象?
我剛開始為我的單元測試和Spring Boot編寫模擬代碼,所以我可能遺漏了一些東西。下面的代碼(試圖簡化名稱并使其成為通用名稱以便在此處發(fā)布)。
我的測試類
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
}
}
用于對數(shù)據(jù)層進行服務調用的類
@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()方法時,變量存儲庫為空,因此當嘗試執(zhí)行repository.findOne(Id)時,它拋出異常n。這就是我嘗試模擬的內容,但存儲庫給我?guī)砹藛栴}。
@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> {
}
推薦答案
首先我要說的是,通過使用構造函數(shù)注入而不是字段注入(這使得使用模擬編寫測試要簡單得多),您走上了正確的道路。
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–>開始調用。但只模擬您的存儲庫調用。
通過這種方式,您可以控制和測試類的所有其他部分(包括服務和數(shù)據(jù)服務),并且只模擬存儲庫調用。
這篇關于單元測試如何使用Mockito模擬存儲庫的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,