4

在阅读了一篇关于 JDK1.8 和 Lambda 表达式的文章后,我意识到我最近几年一直在使用的 ExpectedCondition 块可能适合表示为 Lambda 表达式。

鉴于此等待对象:

Wait<WebDriver> wait = new FluentWait<WebDriver>( driver )
       .withTimeout(30, SECONDS)
       .pollingEvery(5, SECONDS)
       .ignoring( NoSuchElementException.class );

谁能告诉我如何将 Selenium 的 ExpectedCondition 表达式转换为 Lambda 表达式?

  WebElement foo = wait.until( new ExpectedCondition<Boolean>() {
       public WebElement apply( WebDriver webDriver ) {
           return webDriver.findElement( By.id("foo") );
       }
  } );
4

3 回答 3

3

从 Selenium 版本 3.2.0 开始, until() 方法将只接受Function<T,K>作为参数并且Predicate<T>不推荐使用作为参数的方法

上面的决定是使用 lambda 表达式。

所以回答你的问题:

Wait<WebDriver> wait = new FluentWait<WebDriver>( driver )
       .withTimeout(30, SECONDS)
       .pollingEvery(5, SECONDS)
       .ignoring(NoSuchElementException.class);

//lamda expression:
WebElement foo = wait.until(d -> d.findElement(By.id("foo")));
于 2017-08-31T13:17:13.100 回答
2

基本上,虽然lamdas 不仅仅是匿名类- 当您想要讨论动词并在过去必须使用匿名类的地方提供更简洁的代码时,它们确实很有帮助。

我们想告诉 Selinium 等到一个动作发生。使用旧语法,我们必须创建一个新的 ExpectedCondition 接口的匿名实现——使用 lambdas 不再是这种情况。

所以假设 Selinium 将支持这种语法,它应该是这样的:

wait.until(webDriver -> webDriver.findElement(By.id("foo")))

减少代码的长度,使其更具可读性。

更普遍:

new Interface{
    public ReturnValue action(Type first,Type second...){
         return SomeExpression();
    }
}

变成:

(first,second) -> SomeExpression();
于 2013-08-31T21:53:00.843 回答
0

不完全的。在 Java 8 中,我们应该能够用 lambda 替换实现“单一抽象方法接口”的匿名内部类,如下所示:

new FluentWait<WebDriver>( driver )   // Would be nice!
   .withTimeout(30, SECONDS)
   .pollingEvery(5, SECONDS)
   .ignoring( NoSuchElementException.class )
   .until(wd -> wd.findElements(By.id("foo")).size() == 1);

问题在于,这仅在接收方法 FluentWait.until 仅接受一个“单一抽象方法接口”时才有效。因为 until 接受多个,你会得到以下编译时错误:

方法 until(Predicate) 对于 FluentWait 类型不明确

于 2017-03-18T00:00:21.173 回答