我写了一个方法,它接受一个Callable和一个任意长度的字符串数组,我用它来计算Callable的执行时间,然后将结果写入数据库:
public static <T> T logTimes(Callable<T> callable, String actionToTest, String... testData) throws Exception {
LocalDateTime before = null;
T call = null;
try {
before = LocalDateTime.now();
call = callable.call();
logToDocument(before, LocalDateTime.now(), actionToTest, testData);
} catch (TimeoutException ex) {
logToDocument(before, LocalDateTime.now(), actionToTest, testData);
}
return call;
}
这工作得很好,但是我现在遇到了一种情况,我需要将Callable的返回值作为参数传递给相同的方法:
public static String loadedPageName(WebDriver driver, int seconds) throws Exception {
String originPage = pageName(driver);
By loadingBar = By.xpath("//div[contains(@class, 'progress')]");
WebDriverWait w = new WebDriverWait(driver, seconds);
Function<WebDriver, Boolean> pageFinishedLoading = wd -> wd.findElements(loadingBar).size() == 0;
AtomicReference<String> dest = new AtomicReference<>();
try {
return ExtentTestManager.logTimes(()-> {
w.until(ExpectedConditions.presenceOfAllElementsLocatedBy(loadingBar));
w.until(pageFinishedLoading);
dest.set(driver.findElement(By.tagName("body")).getAttribute("page-name"));
return dest;
}, REDIRECT, ORIGIN, originPage, DESTINATION, dest.get()).get();
} catch (TimeoutException ex) {
ExtentTestManager.reporterLog("Timeout after waiting ".concat(String.valueOf(seconds)).concat(" seconds for a page to load"));
ExtentTestManager.logToDocument(LocalDateTime.now(), seconds, REDIRECT, ORIGIN, originPage, DESTINATION, "timeout");
return null;
}
}
此方法等待页面加载完成并返回加载页面的名称。我想将该返回值用作ExtentTestManager.logTimes(Callable<T> callable, String actionToTest, String... testData)
调用中的参数,而Callable<T> callable
是其参数之一。
就像现在一样,loadedPageName(WebDriver driver, int seconds)
返回预期的页面名称,但logTimes
将null
写入数据库以获取callable
的结果。
有办法做到这一点吗?
您在logTimes中的代码相当于:
try {
before = LocalDateTime.now();
call = callable.call();
} catch (TimeoutException ex) {
// do nothing with the exception
}
logToDocument(before, LocalDateTime.now(), actionToTest, testData);
也许你想用TimeoutException做点什么?此外,loaddpagename中的调用代码将永远不会遇到TimeoutException,因为它已经在logTimes中被捕获(并被忽略)。
关于你的问题,最后一个testData值有问题:dest.get()
。当它被求值时(在执行logTimes方法之前),它还没有被值填充。可能这就是你的问题:你正在传递空AtomicReference的值作为testData用于logTimes显示。
你在Callable被执行之前传入testData字符串,所以Callable的结果永远不会是这个testData的一部分。如果需要可调用对象的结果,可以编辑logTimes方法,使其始终使用可调用对象的结果作为第一个/最后一个testData,例如:
public static <T> T logTimes(Callable<T> callable, String actionToTest, String... testData) throws Exception {
LocalDateTime before = LocalDateTime.now();
T call = callable.call();
List<String> allTestData = new ArrayList<String>(Arrays.asList(testData));
allTestData.add(String.valueOf(call));
logToDocument(before, LocalDateTime.now(), actionToTest, allTestData.toArray(new String[0]));
return call;
}