Mockito doThrow() 没有按照我的预期行事
Mockito doThrow() not acting as I expect
我正在处理与使用 WebDrivers、WebElements 等的项目相关的单元测试。我在模拟连接和所有方面都走得很远,但我遇到了一个问题。
我的 class 中有一个 try 块看起来类似于
class MyClass {
myMethod() {
(...)
try {
WebElement element = webDriver.findElement(By.id(elementId));
element.click();
} catch (NoSuchElementException e) {
throw new MyException("Unable to locate element!", e);
}
(...)
}
}
现在我正在尝试编写一个未找到该元素的测试用例
class MyTestClass {
testMyMethod() {
WebElement mockedElement = Mockito.mock(WebElement.class);
Mockito.when(mockedWebDriver.findElement(By.id(Mockito.anyString()))).thenReturn(mockedElement);
Mockito.doThrow(NoSuchElementException.class).when(mockedAllowElement).click();
try {
mockedObjectOfMyClass.myMethod()
Assert.fail();
} catch (MyException e) {
Assert.assertTrue(e.getCause() instanceof NoSuchElementException);
}
}
}
我的问题是我得到了可爱的 NoSuchElementException 而不是预期的 MyException:
java.util.NoSuchElementException
Process finished with exit code -1
我检查了所有我能想到的。在测试过程中,测试方法中所有模拟对象的 hashCode 与真实方法中的相同,myMethod 运行到 "element.click()"。但是异常没有被catch块捕获。
我一定是遗漏了一些东西,我对 Mockito 和 UnitTesting 还很陌生。
希望我在缩短我的逻辑时没有遗漏任何重要的东西:)。
我将不胜感激任何想法或提示
(编辑)
感谢您的快速回复,这里是完整的堆栈跟踪:
java.util.NoSuchElementException: this is mine
at yandex.TokenGeneratorTest.testGetVerificationCodeNoElement(TokenGeneratorTest.java:308)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at org.junit.runners.model.FrameworkMethod.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.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access[=13=]0(ParentRunner.java:58)
at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:268)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:78)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:212)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:68)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
我认为您应该重构代码以使测试更容易。如果它是遗留代码,那么你就得靠自己了。
方法 testMyMethod() 可能会请求 webDriver 并声明抛出异常 NoSuchElementException。
所以有类似
的东西
class MyTestClass {
testMyMethod(WebDriver webDriver) throws NoSuchElementException {
...
}
现在你的测试可能如下所示。
class MyTestClass {
@Test(expected = NoSuchElementException.class)
testMyMethod() {
WebDriver mockedWebDriver = Mockito.mock(WebDriver.class);
WebElement mockedElement = Mockito.mock(WebElement.class);
Mockito.doThrow(NoSuchElementException.class).when(mockedElement).click();
Mockito.when( mockedWebDriver.findElement( By.id( Mockito.anyString()))).thenReturn( mockedElement);
MyClass myClass = new MyClass();
myClass.myMethod(mockedWebDriver)
}
}
此外,我高度怀疑是在调用 findElement(...) 期间抛出异常,而不是在单击期间抛出异常。但我猜你离代码更近了。
感谢您的所有想法。
我刚刚度过了一个 "watch out when using alt + enter" 时刻。
代码工作得很好,除了我的测试方法抛出了一个 java.util.NoSuchElementException
而不是我的代码捕获的 org.openqa.selenium.NoSuchElementException
。
更改此设置解决了我的问题,再次感谢您的宝贵时间:)
我正在处理与使用 WebDrivers、WebElements 等的项目相关的单元测试。我在模拟连接和所有方面都走得很远,但我遇到了一个问题。
我的 class 中有一个 try 块看起来类似于
class MyClass {
myMethod() {
(...)
try {
WebElement element = webDriver.findElement(By.id(elementId));
element.click();
} catch (NoSuchElementException e) {
throw new MyException("Unable to locate element!", e);
}
(...)
}
}
现在我正在尝试编写一个未找到该元素的测试用例
class MyTestClass {
testMyMethod() {
WebElement mockedElement = Mockito.mock(WebElement.class);
Mockito.when(mockedWebDriver.findElement(By.id(Mockito.anyString()))).thenReturn(mockedElement);
Mockito.doThrow(NoSuchElementException.class).when(mockedAllowElement).click();
try {
mockedObjectOfMyClass.myMethod()
Assert.fail();
} catch (MyException e) {
Assert.assertTrue(e.getCause() instanceof NoSuchElementException);
}
}
}
我的问题是我得到了可爱的 NoSuchElementException 而不是预期的 MyException:
java.util.NoSuchElementException
Process finished with exit code -1
我检查了所有我能想到的。在测试过程中,测试方法中所有模拟对象的 hashCode 与真实方法中的相同,myMethod 运行到 "element.click()"。但是异常没有被catch块捕获。
我一定是遗漏了一些东西,我对 Mockito 和 UnitTesting 还很陌生。
希望我在缩短我的逻辑时没有遗漏任何重要的东西:)。
我将不胜感激任何想法或提示
(编辑)
感谢您的快速回复,这里是完整的堆栈跟踪:
java.util.NoSuchElementException: this is mine
at yandex.TokenGeneratorTest.testGetVerificationCodeNoElement(TokenGeneratorTest.java:308)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at org.junit.runners.model.FrameworkMethod.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.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access[=13=]0(ParentRunner.java:58)
at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:268)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:78)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:212)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:68)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
我认为您应该重构代码以使测试更容易。如果它是遗留代码,那么你就得靠自己了。
方法 testMyMethod() 可能会请求 webDriver 并声明抛出异常 NoSuchElementException。
所以有类似
的东西 class MyTestClass {
testMyMethod(WebDriver webDriver) throws NoSuchElementException {
...
}
现在你的测试可能如下所示。
class MyTestClass {
@Test(expected = NoSuchElementException.class)
testMyMethod() {
WebDriver mockedWebDriver = Mockito.mock(WebDriver.class);
WebElement mockedElement = Mockito.mock(WebElement.class);
Mockito.doThrow(NoSuchElementException.class).when(mockedElement).click();
Mockito.when( mockedWebDriver.findElement( By.id( Mockito.anyString()))).thenReturn( mockedElement);
MyClass myClass = new MyClass();
myClass.myMethod(mockedWebDriver)
}
}
此外,我高度怀疑是在调用 findElement(...) 期间抛出异常,而不是在单击期间抛出异常。但我猜你离代码更近了。
感谢您的所有想法。
我刚刚度过了一个 "watch out when using alt + enter" 时刻。
代码工作得很好,除了我的测试方法抛出了一个 java.util.NoSuchElementException
而不是我的代码捕获的 org.openqa.selenium.NoSuchElementException
。
更改此设置解决了我的问题,再次感谢您的宝贵时间:)