[英]Mockito verify the call to a mock method inside a mock call
我有模型模擬類,在其中可以驗證來自另一個DAO模擬對象的調用。 但是此調用不會在模型類上發生,而僅在DAO類上進行驗證。
public class ApplicationTests {
@Mock
private Card card;
@Mock
private JourneyDAO journeyDAO;
@InjectMocks
private JourneyServiceImpl journeyServiceImpl;
private static final Double ZERO_VALUE = 0.0;
private static final Double INITIAL_BALANCE = 30D;
private static final String NAME = "name";
@Before
public void setUp() {
when(card.getBalance()).thenReturn(INITIAL_BALANCE);
when(card.getName()).thenReturn(NAME);
}
@Test
public void startJourneyInZone1_Test() {
barrier = new Barrier(card, direction.IN, journeyType.TUBE, Stations.Holborn);
journeyServiceImpl.startTubeJourney(barrier);
verify(card, times(1)).addBalance(MAX_FARE * -1);// this call is not heppening
verify(journeyDAO, times(1)).startTubeJourney(barrier);// this is working
}
}
DAO類的方法如下圖
public void startTubeJourney(Barrier barrier) {
if(barrier.getModeOfJourney() == TravelMode.TUBE) {
if(barrier.getDirection() == Direction.IN) {
boardingAtZone = barrier.getZone();
barrier.getCard().addBalance(MAX_FARE * -1);
}
}
}
運行測試時出現錯誤提示。 請忽略包和類名不匹配的情況,因為我正在舉一些示例案例。
Wanted but not invoked:
card.addBalance(0.7000000000000002d);
-> at com.rcard.travel.ApplicationTests.endTubeJourneyTest(ApplicationTests.java:69)
Actually, there were zero interactions with this mock.
at com.travel.ApplicationTests.endTubeJourneyTest(ApplicationTests.java:69)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.springframework.test.context.junit4.statements.RunBeforeTestExecutionCallbacks.evaluate(RunBeforeTestExecutionCallbacks.java:73)
at org.springframework.test.context.junit4.statements.RunAfterTestExecutionCallbacks.evaluate(RunAfterTestExecutionCallbacks.java:83)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:251)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:678)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
屏障類看起來像
public class Barrier {
private Card card;
private Direction direction;
private TravelMode modeOfJourney;
private Stations zone;
public Barrier(Card card, Direction direction, TravelMode mode, Stations zone) {
this.card = card;
this.direction = direction;
this.modeOfJourney = mode;
this.zone = zone;
}
public String getZone() {
return Stations.elementOf(this.zone);
}
public void setZone(Stations zone) {
this.zone = zone;
}
public Card getCard() {
return card;
}
public void setCard(Card card) {
this.card = card;
}
public Direction getDirection() {
return direction;
}
public void setDirection(Direction direction) {
this.direction = direction;
}
public TravelMode getModeOfJourney() {
return modeOfJourney;
}
public void setModeOfJourney(TravelMode modeOfJourney) {
this.modeOfJourney = modeOfJourney;
}
}
由於journeyDAO
是一個模擬,因此這意味着未調用真實的journeyDAO.startTubeJourney()
。
一種可能的解決方法是使用一個真正的JourneyDAO
,因此card.addBalance()
確實會被調用,但這確實意味着一個測試正在測試服務類和DAO類。
另外,我很想為JourneyDAO
編寫一個單獨的測試。 這可以調用其startTubeJourney()
,並驗證card.addBalance()
。 這意味着針對模擬journeyDAO.startTubeJourney()
的當前verify()
journeyDAO.startTubeJourney()
可以保留。
問題在於線
@Mock
private JourneyDAO journeyDAO;
您正在嘗試驗證屬於journeyDAO
對象journeyDAO
。 如果您想擁有when...then
在可用時調用真實方法,則需要使用@Spy
注釋。
@Spy
private JourneyDAO journeyDAO;
將解決此問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.