Мое первое желание - , чтобы не издеваться над этим : похоже, startAsync
является частью открытого API MyClassImplementRunner, и что вы должны тестировать эти части вместе.В тестовом классе, таком как MyClassImplementRunnerTest, имеет смысл рассматривать тестируемую систему как MyClassImplementRunner, не пытаясь разделить ее.В противном случае очень легко потерять след того, что вы тестируете , включая что реально против что такое макет .
Еслисуществует любое внешнее условие, которое ищет MyClassImplementRunner, вы можете смоделировать эту зависимость, которая, вероятно, приведет к немедленному возвращению вашего CompletableFuture;тем не менее, вы показали нам только один параметр String.
Тем не менее, вполне возможно, что startAsync
содержит логику, которую вы хотите полностью протестировать без реального MyClassImplementRunner.В этом случае вы можете создать перегрузку для тестирования, возможно, с ограниченной видимостью или аннотации только для теста , чтобы указать, что он не должен вызываться в рабочей среде.
public static CompletableFuture<Void> startAsync(String param1) {
return startAsync(new MyClassImplementRunner(param1);
}
/** Package-private, for a test class in the same package. */
@VisibleForTesting static CompletableFuture<Void> startAsync(Runnable task) {
return CompletableFuture.runAsync(task).whenComplete(
(response, throwable) -> {
//some code when complete
});
}
Путем разделениятеперь вы можете запускать startAsync(new Runnable())
в тестах, чтобы имитировать мгновенно выполняющуюся задачу, и запускать startAsync(() -> { throw new RuntimeException(); })
, чтобы имитировать быстро проваливающуюся задачу.Это позволяет вам тестировать startAsync
независимо от MyClassImplementRunner.
Может показаться нецелесообразным проводить рефакторинг для тестирования или вводить методы, предназначенные только для тестирования, и это справедливая оценка. будет проверено именно так, как его запустят потребители, без насмешек.Однако, если вы говорите, что в тестах гораздо удобнее запускать с другим Runnable, чем MyClassImplementRunner, вы контролируете код и можете подготовиться к этому, включив в код соответствующую гибкость («тестовый шов»)вы контролируетеНа самом деле, если startAsync
является достаточно отдельным методом, который может принимать произвольный Runnable, вы можете выделить его как отдельный метод с отдельным тестированием.