• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

temporalio / sdk-java / #351

04 Aug 2026 11:58PM UTC coverage: 67.781% (-0.5%) from 68.245%
#351

push

github

web-flow
Add dev server downloader & runner to testing package (#2982)

7311 of 12876 branches covered (56.78%)

Branch coverage included in aggregate %.

331 of 703 new or added lines in 12 files covered. (47.08%)

28 existing lines in 13 files now uncovered.

30207 of 42476 relevant lines covered (71.12%)

0.71 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

78.49
/temporal-testing/src/main/java/io/temporal/testing/TestWorkflowRule.java
1
package io.temporal.testing;
2

3
import static io.temporal.testing.internal.TestServiceUtils.applyNexusServiceOptions;
4

5
import com.uber.m3.tally.Scope;
6
import io.temporal.api.common.v1.WorkflowExecution;
7
import io.temporal.api.enums.v1.IndexedValueType;
8
import io.temporal.api.history.v1.History;
9
import io.temporal.api.nexus.v1.Endpoint;
10
import io.temporal.api.workflowservice.v1.WorkflowServiceGrpc;
11
import io.temporal.client.ActivityClient;
12
import io.temporal.client.ActivityClientOptions;
13
import io.temporal.client.WorkflowClient;
14
import io.temporal.client.WorkflowClientOptions;
15
import io.temporal.client.WorkflowOptions;
16
import io.temporal.client.WorkflowStub;
17
import io.temporal.common.Experimental;
18
import io.temporal.common.SearchAttributeKey;
19
import io.temporal.common.interceptors.WorkerInterceptor;
20
import io.temporal.internal.common.env.DebugModeUtils;
21
import io.temporal.internal.docker.RegisterTestNamespace;
22
import io.temporal.serviceclient.WorkflowServiceStubs;
23
import io.temporal.serviceclient.WorkflowServiceStubsOptions;
24
import io.temporal.worker.*;
25
import java.time.Instant;
26
import java.util.HashMap;
27
import java.util.Map;
28
import java.util.UUID;
29
import javax.annotation.Nonnull;
30
import javax.annotation.Nullable;
31
import org.junit.Test;
32
import org.junit.rules.TestRule;
33
import org.junit.rules.TestWatcher;
34
import org.junit.rules.Timeout;
35
import org.junit.runner.Description;
36
import org.junit.runners.model.Statement;
37

38
/**
39
 * JUnit4
40
 *
41
 * <p>Test rule that sets up test environment, simplifying workflow worker creation and shutdown.
42
 * Can be used with both in-memory and standalone temporal service. (see {@link
43
 * Builder#setUseExternalService(boolean)} and {@link Builder#setTarget(String)}})
44
 *
45
 * <p>Example of usage:
46
 *
47
 * <pre><code>
48
 *   public class MyTest {
49
 *
50
 *  {@literal @}Rule
51
 *   public TestWorkflowRule workflowRule =
52
 *       TestWorkflowRule.newBuilder()
53
 *           .setWorkflowTypes(TestWorkflowImpl.class)
54
 *           .setActivityImplementations(new TestActivities())
55
 *           .build();
56
 *
57
 *  {@literal @}Test
58
 *   public void testMyWorkflow() {
59
 *       TestWorkflow workflow = workflowRule.getWorkflowClient().newWorkflowStub(
60
 *                 TestWorkflow.class, WorkflowOptions.newBuilder().setTaskQueue(workflowRule.getTaskQueue()).build());
61
 *       ...
62
 *   }
63
 * </code></pre>
64
 */
65
public class TestWorkflowRule implements TestRule {
66

67
  private final String namespace;
68
  private final boolean useExternalService;
69
  private final boolean useDevServer;
70
  private final boolean doNotStart;
71
  private final boolean doNotSetupNexusEndpoint;
72
  @Nullable private final Timeout globalTimeout;
73

74
  private final Class<?>[] workflowTypes;
75
  private final Object[] activityImplementations;
76
  private final Object[] nexusServiceImplementations;
77
  private final WorkflowServiceStubsOptions serviceStubsOptions;
78
  private final WorkflowClientOptions clientOptions;
79
  private final ActivityClientOptions activityClientOptions;
80
  private final WorkerFactoryOptions workerFactoryOptions;
81
  private final WorkflowImplementationOptions workflowImplementationOptions;
82
  private final WorkerOptions workerOptions;
83
  private final String target;
84
  private final boolean useTimeskipping;
85
  private final Scope metricsScope;
86
  private String uniquePostfix;
87

88
  @Nonnull private final Map<String, IndexedValueType> searchAttributes;
89

90
  private String taskQueue;
91
  private String nexusEndpointName;
92
  private Endpoint nexusEndpoint;
93
  private final TestWorkflowEnvironment testEnvironment;
94
  private final TestWatcher watchman =
1✔
95
      new TestWatcher() {
1✔
96
        @Override
97
        protected void failed(Throwable e, Description description) {
NEW
98
          if (!useExternalService && !useDevServer) {
×
NEW
99
            System.err.println(
×
NEW
100
                "WORKFLOW EXECUTION HISTORIES:\n" + testEnvironment.getDiagnostics());
×
101
          }
UNCOV
102
        }
×
103
      };
104

105
  private TestWorkflowRule(Builder builder) {
1✔
106
    this.doNotStart = builder.doNotStart;
1✔
107
    this.doNotSetupNexusEndpoint = builder.doNotSetupNexusEndpoint;
1✔
108
    this.useExternalService = builder.useExternalService;
1✔
109
    this.useDevServer = builder.useDevServer;
1✔
110
    this.namespace =
1✔
111
        (builder.namespace == null) ? RegisterTestNamespace.NAMESPACE : builder.namespace;
1!
112
    this.workflowTypes = (builder.workflowTypes == null) ? new Class[0] : builder.workflowTypes;
1✔
113
    this.activityImplementations =
1✔
114
        (builder.activityImplementations == null) ? new Object[0] : builder.activityImplementations;
1✔
115
    this.nexusServiceImplementations =
1✔
116
        (builder.nexusServiceImplementations == null)
1✔
117
            ? new Object[0]
1✔
118
            : builder.nexusServiceImplementations;
1✔
119
    this.serviceStubsOptions =
1✔
120
        (builder.workflowServiceStubsOptions == null)
1✔
121
            ? WorkflowServiceStubsOptions.newBuilder().build()
1✔
122
            : builder.workflowServiceStubsOptions;
1✔
123
    this.clientOptions =
1✔
124
        (builder.workflowClientOptions == null)
1✔
125
            ? WorkflowClientOptions.newBuilder().setNamespace(namespace).build()
1✔
126
            : builder.workflowClientOptions.toBuilder().setNamespace(namespace).build();
1✔
127
    this.activityClientOptions = builder.activityClientOptions;
1✔
128
    this.workerOptions =
1✔
129
        (builder.workerOptions == null)
1✔
130
            ? WorkerOptions.newBuilder().build()
1✔
131
            : builder.workerOptions;
1✔
132
    this.workerFactoryOptions =
1✔
133
        (builder.workerFactoryOptions == null)
1✔
134
            ? WorkerFactoryOptions.newBuilder().build()
1✔
135
            : builder.workerFactoryOptions;
1✔
136
    this.workflowImplementationOptions =
1✔
137
        (builder.workflowImplementationOptions == null)
1✔
138
            ? WorkflowImplementationOptions.newBuilder().build()
1✔
139
            : builder.workflowImplementationOptions;
1✔
140
    this.globalTimeout =
1✔
141
        !DebugModeUtils.isTemporalDebugModeOn() && builder.testTimeoutSeconds != 0
1!
142
            ? Timeout.seconds(builder.testTimeoutSeconds)
×
143
            : null;
1✔
144

145
    this.target = builder.target;
1✔
146
    this.useTimeskipping = builder.useTimeskipping;
1✔
147
    this.metricsScope = builder.metricsScope;
1✔
148
    this.searchAttributes = builder.searchAttributes;
1✔
149

150
    TestEnvironmentOptions testEnvironmentOptions = createTestEnvOptions(builder.initialTimeMillis);
1✔
151
    this.testEnvironment =
1✔
152
        useDevServer
1!
NEW
153
            ? TestWorkflowEnvironment.startLocal(testEnvironmentOptions, builder.devServerOptions)
×
154
            : TestWorkflowEnvironment.newInstance(testEnvironmentOptions);
1✔
155
  }
1✔
156

157
  protected TestEnvironmentOptions createTestEnvOptions(long initialTimeMillis) {
158
    return TestEnvironmentOptions.newBuilder()
1✔
159
        .setWorkflowServiceStubsOptions(serviceStubsOptions)
1✔
160
        .setWorkflowClientOptions(clientOptions)
1✔
161
        .setActivityClientOptions(activityClientOptions)
1✔
162
        .setWorkerFactoryOptions(workerFactoryOptions)
1✔
163
        .setUseExternalService(useExternalService)
1✔
164
        .setUseTimeskipping(useTimeskipping)
1✔
165
        .setTarget(target)
1✔
166
        .setInitialTimeMillis(initialTimeMillis)
1✔
167
        .setMetricsScope(metricsScope)
1✔
168
        .setSearchAttributes(searchAttributes)
1✔
169
        .build();
1✔
170
  }
171

172
  public static Builder newBuilder() {
173
    return new Builder();
1✔
174
  }
175

176
  public static class Builder {
177

178
    private String namespace;
179
    private String target;
180
    private boolean useExternalService;
181
    private boolean useDevServer;
182
    private TemporalDevServerOptions devServerOptions =
1✔
183
        TemporalDevServerOptions.getDefaultInstance();
1✔
184
    private boolean doNotStart;
185
    private boolean doNotSetupNexusEndpoint;
186
    private long initialTimeMillis;
187
    // Default to TestEnvironmentOptions isUseTimeskipping
188
    private boolean useTimeskipping =
1✔
189
        TestEnvironmentOptions.getDefaultInstance().isUseTimeskipping();
1✔
190

191
    private Class<?>[] workflowTypes;
192
    private Object[] activityImplementations;
193
    private Object[] nexusServiceImplementations;
194
    private WorkflowServiceStubsOptions workflowServiceStubsOptions;
195
    private WorkflowClientOptions workflowClientOptions;
196
    private ActivityClientOptions activityClientOptions;
197
    private WorkerFactoryOptions workerFactoryOptions;
198
    private WorkflowImplementationOptions workflowImplementationOptions;
199
    private WorkerOptions workerOptions;
200
    private long testTimeoutSeconds;
201
    @Nonnull private final Map<String, IndexedValueType> searchAttributes = new HashMap<>();
1✔
202
    private Scope metricsScope;
203

204
    protected Builder() {}
1✔
205

206
    public Builder setWorkerOptions(WorkerOptions options) {
207
      this.workerOptions = options;
1✔
208
      return this;
1✔
209
    }
210

211
    public void setWorkflowServiceStubsOptions(
212
        WorkflowServiceStubsOptions workflowServiceStubsOptions) {
213
      this.workflowServiceStubsOptions = workflowServiceStubsOptions;
1✔
214
    }
1✔
215

216
    /**
217
     * Override {@link WorkflowClientOptions} for test environment. If set, takes precedence over
218
     * {@link #setNamespace(String) namespace}.
219
     */
220
    public Builder setWorkflowClientOptions(WorkflowClientOptions workflowClientOptions) {
221
      this.workflowClientOptions = workflowClientOptions;
1✔
222
      return this;
1✔
223
    }
224

225
    /** Override {@link ActivityClientOptions} for test environment. */
226
    public Builder setActivityClientOptions(ActivityClientOptions activityClientOptions) {
227
      this.activityClientOptions = activityClientOptions;
1✔
228
      return this;
1✔
229
    }
230

231
    public Builder setWorkerFactoryOptions(WorkerFactoryOptions options) {
232
      this.workerFactoryOptions = options;
1✔
233
      return this;
1✔
234
    }
235

236
    public Builder setNamespace(String namespace) {
237
      this.namespace = namespace;
×
238
      return this;
×
239
    }
240

241
    public Builder setWorkflowTypes(Class<?>... workflowTypes) {
242
      this.workflowTypes = workflowTypes;
1✔
243
      return this;
1✔
244
    }
245

246
    public Builder setWorkflowTypes(
247
        WorkflowImplementationOptions implementationOptions, Class<?>... workflowTypes) {
248
      this.workflowImplementationOptions = implementationOptions;
1✔
249
      this.workflowTypes = workflowTypes;
1✔
250
      return this;
1✔
251
    }
252

253
    /**
254
     * Specify Nexus service implementations to register with the Temporal worker. If any Nexus
255
     * services are registered with the worker, the rule will automatically create a Nexus Endpoint
256
     * for the test and the endpoint will be set on the per-service options and default options in
257
     * {@link WorkflowImplementationOptions} if none are provided.
258
     *
259
     * <p>This can be disabled by setting {@link #setDoNotSetupNexusEndpoint(boolean)} to true.
260
     *
261
     * @see Worker#registerNexusServiceImplementation(Object...)
262
     */
263
    public Builder setNexusServiceImplementation(Object... nexusServiceImplementations) {
264
      this.nexusServiceImplementations = nexusServiceImplementations;
1✔
265
      return this;
1✔
266
    }
267

268
    public Builder setActivityImplementations(Object... activityImplementations) {
269
      this.activityImplementations = activityImplementations;
1✔
270
      return this;
1✔
271
    }
272

273
    /**
274
     * Switches between in-memory and external temporal service implementations.
275
     *
276
     * <p>External-service and dev-server modes are mutually exclusive. Calling this method clears
277
     * any selection made by {@link #useDevServer()} or {@link
278
     * #useDevServer(TemporalDevServerOptions)}; whichever method is called last determines the
279
     * service used by the rule.
280
     *
281
     * @param useExternalService use external service if true.
282
     *     <p>Default is false.
283
     */
284
    public Builder setUseExternalService(boolean useExternalService) {
UNCOV
285
      this.useExternalService = useExternalService;
×
NEW
286
      this.useDevServer = false;
×
NEW
287
      return this;
×
288
    }
289

290
    /**
291
     * Uses an owned local Temporal dev server instead of the in-memory or external service.
292
     *
293
     * <p>The rule closes the server during normal teardown. Dev-server tests do not support time
294
     * skipping.
295
     *
296
     * <p>Dev-server and external-service modes are mutually exclusive. Calling this method clears
297
     * any selection made by {@link #setUseExternalService(boolean)}; whichever method is called
298
     * last determines the service used by the rule.
299
     */
300
    @Experimental
301
    public Builder useDevServer() {
NEW
302
      return useDevServer(TemporalDevServerOptions.getDefaultInstance());
×
303
    }
304

305
    /**
306
     * Uses an owned local Temporal dev server with the supplied options.
307
     *
308
     * <p>Dev-server and external-service modes are mutually exclusive. Calling this method clears
309
     * any selection made by {@link #setUseExternalService(boolean)}; whichever method is called
310
     * last determines the service used by the rule.
311
     *
312
     * <pre>{@code
313
     * TestWorkflowRule.newBuilder()
314
     *     .useDevServer(
315
     *         TemporalDevServerOptions.newBuilder().setDownloadVersion("v1.7.2").build())
316
     *     .setWorkflowTypes(MyWorkflowImpl.class)
317
     *     .build();
318
     * }</pre>
319
     */
320
    @Experimental
321
    public Builder useDevServer(@Nonnull TemporalDevServerOptions options) {
NEW
322
      if (options == null) {
×
NEW
323
        throw new NullPointerException("options");
×
324
      }
NEW
325
      this.useDevServer = true;
×
NEW
326
      this.useExternalService = false;
×
NEW
327
      this.target = null;
×
NEW
328
      this.devServerOptions = options;
×
UNCOV
329
      return this;
×
330
    }
331

332
    /**
333
     * Sets TestEnvironmentOptions.setUseTimeskippings. If true, no actual wall-clock time will pass
334
     * when a workflow sleeps or sets a timer.
335
     *
336
     * <p>Default is true
337
     */
338
    public Builder setUseTimeskipping(boolean useTimeskipping) {
339
      this.useTimeskipping = useTimeskipping;
1✔
340
      return this;
1✔
341
    }
342

343
    /**
344
     * Optional parameter that defines an endpoint which will be used for the communication with
345
     * standalone temporal service. Has no effect if {@link #setUseExternalService(boolean)} is set
346
     * to false.
347
     *
348
     * <p>Default is to use 127.0.0.1:7233
349
     */
350
    public Builder setTarget(String target) {
351
      this.target = target;
×
352
      return this;
×
353
    }
354

355
    /**
356
     * @deprecated Temporal test rule shouldn't be responsible for enforcing test timeouts. Use
357
     *     toolchain of your test framework to enforce timeouts.
358
     */
359
    @Deprecated
360
    public Builder setTestTimeoutSeconds(long testTimeoutSeconds) {
361
      this.testTimeoutSeconds = testTimeoutSeconds;
×
362
      return this;
×
363
    }
364

365
    /**
366
     * Set the initial time for the workflow virtual clock, milliseconds since epoch.
367
     *
368
     * <p>Default is current time
369
     */
370
    public Builder setInitialTimeMillis(long initialTimeMillis) {
371
      this.initialTimeMillis = initialTimeMillis;
1✔
372
      return this;
1✔
373
    }
374

375
    /**
376
     * Set the initial time for the workflow virtual clock.
377
     *
378
     * <p>Default is current time
379
     */
380
    public Builder setInitialTime(Instant initialTime) {
381
      this.initialTimeMillis = initialTime.toEpochMilli();
×
382
      return this;
×
383
    }
384

385
    /**
386
     * When set to true the {@link TestWorkflowEnvironment#start()} is not called by the rule before
387
     * executing the test. This to support tests that register activities and workflows with workers
388
     * directly instead of using only {@link TestWorkflowRule.Builder}.
389
     */
390
    public Builder setDoNotStart(boolean doNotStart) {
391
      this.doNotStart = doNotStart;
1✔
392
      return this;
1✔
393
    }
394

395
    /**
396
     * When set to true the {@link TestWorkflowEnvironment} will not automatically create a Nexus
397
     * Endpoint. This is useful when you want to manually create a Nexus Endpoint for your test.
398
     */
399
    public Builder setDoNotSetupNexusEndpoint(boolean doNotSetupNexusEndpoint) {
400
      this.doNotSetupNexusEndpoint = doNotSetupNexusEndpoint;
×
401
      return this;
×
402
    }
403

404
    /**
405
     * Add a search attribute to be registered on the Temporal Server.
406
     *
407
     * @param name name of the search attribute
408
     * @param type search attribute type
409
     * @return {@code this}
410
     * @see <a
411
     *     href="https://docs.temporal.io/self-hosted-guide/visibility#create-custom-search-attributes">
412
     *     How to create custom Search Attributes</a>
413
     */
414
    public Builder registerSearchAttribute(String name, IndexedValueType type) {
415
      this.searchAttributes.put(name, type);
1✔
416
      return this;
1✔
417
    }
418

419
    /**
420
     * Add a search attribute to be registered on the Temporal Server.
421
     *
422
     * @param key key to register
423
     * @return {@code this}
424
     * @see <a
425
     *     href="https://docs.temporal.io/self-hosted-guide/visibility#create-custom-search-attributes">
426
     *     How to create custom Search Attributes</a>
427
     */
428
    public Builder registerSearchAttribute(SearchAttributeKey<?> key) {
429
      return this.registerSearchAttribute(key.getName(), key.getValueType());
1✔
430
    }
431

432
    /**
433
     * Sets the scope to be used for metrics reporting. Optional. Default is to not report metrics.
434
     *
435
     * <p>Note: Don't mock {@link Scope} in tests! If you need to verify the metrics behavior,
436
     * create a real Scope and mock, stub or spy a reporter instance:<br>
437
     *
438
     * <pre>{@code
439
     * StatsReporter reporter = mock(StatsReporter.class);
440
     * Scope metricsScope =
441
     *     new RootScopeBuilder()
442
     *         .reporter(reporter)
443
     *         .reportEvery(com.uber.m3.util.Duration.ofMillis(10));
444
     * }</pre>
445
     *
446
     * @param metricsScope the scope to be used for metrics reporting.
447
     * @return {@code this}
448
     */
449
    public Builder setMetricsScope(Scope metricsScope) {
450
      this.metricsScope = metricsScope;
1✔
451
      return this;
1✔
452
    }
453

454
    public TestWorkflowRule build() {
455
      return new TestWorkflowRule(this);
1✔
456
    }
457
  }
458

459
  @Override
460
  public Statement apply(Statement base, Description description) {
461
    taskQueue = init(description);
1✔
462
    Statement testWorkflowStatement =
1✔
463
        new Statement() {
1✔
464
          @Override
465
          public void evaluate() throws Throwable {
466
            Throwable testFailure = null;
1✔
467
            try {
468
              start();
1✔
469
              base.evaluate();
1✔
470
            } catch (Throwable failure) {
1✔
471
              testFailure = failure;
1✔
472
              throw failure;
1✔
473
            } finally {
474
              try {
475
                shutdown();
1✔
NEW
476
              } catch (Throwable cleanupFailure) {
×
NEW
477
                if (testFailure == null) {
×
NEW
478
                  throw cleanupFailure;
×
479
                }
NEW
480
                testFailure.addSuppressed(cleanupFailure);
×
481
              }
1✔
482
            }
483
          }
1✔
484
        };
485

486
    Test annotation = description.getAnnotation(Test.class);
1✔
487
    boolean timeoutIsOverriddenOnTestAnnotation = annotation != null && annotation.timeout() > 0;
1✔
488

489
    if (globalTimeout != null && !timeoutIsOverriddenOnTestAnnotation) {
1!
490
      testWorkflowStatement = globalTimeout.apply(testWorkflowStatement, description);
×
491
    }
492

493
    return watchman.apply(testWorkflowStatement, description);
1✔
494
  }
495

496
  private String init(Description description) {
497
    uniquePostfix = description.getMethodName() + "-" + UUID.randomUUID();
1✔
498
    String taskQueue = "WorkflowTest-" + uniquePostfix;
1✔
499
    nexusEndpointName = String.format("WorkflowTestNexusEndpoint-%s", UUID.randomUUID());
1✔
500

501
    WorkerOptions workerOptions = this.workerOptions;
1✔
502
    Worker worker = testEnvironment.newWorker(taskQueue, workerOptions);
1✔
503
    WorkflowImplementationOptions workflowImplementationOptions =
1✔
504
        this.workflowImplementationOptions;
505
    if (!doNotSetupNexusEndpoint) {
1!
506
      workflowImplementationOptions =
1✔
507
          applyNexusServiceOptions(
1✔
508
              workflowImplementationOptions, nexusServiceImplementations, nexusEndpointName);
509
    }
510
    worker.registerWorkflowImplementationTypes(workflowImplementationOptions, workflowTypes);
1✔
511
    worker.registerActivitiesImplementations(activityImplementations);
1✔
512
    worker.registerNexusServiceImplementation(nexusServiceImplementations);
1✔
513
    return taskQueue;
1✔
514
  }
515

516
  private void start() {
517
    if (!doNotSetupNexusEndpoint && nexusServiceImplementations.length > 0) {
1!
518
      nexusEndpoint = testEnvironment.createNexusEndpoint(nexusEndpointName, taskQueue);
1✔
519
    }
520
    if (!doNotStart) {
1✔
521
      testEnvironment.start();
1✔
522
    }
523
  }
1✔
524

525
  protected void shutdown() {
526
    if (nexusEndpoint != null && !testEnvironment.getOperatorServiceStubs().isShutdown()) {
1✔
527
      testEnvironment.deleteNexusEndpoint(nexusEndpoint);
1✔
528
    }
529
    testEnvironment.close();
1✔
530
  }
1✔
531

532
  /**
533
   * See {@link Builder#setUseExternalService(boolean)}
534
   *
535
   * @return true if the rule is using external temporal service.
536
   */
537
  public boolean isUseExternalService() {
538
    return useExternalService;
×
539
  }
540

541
  public TestWorkflowEnvironment getTestEnvironment() {
542
    return testEnvironment;
1✔
543
  }
544

545
  /**
546
   * @return name of the task queue that test worker is polling.
547
   */
548
  public String getTaskQueue() {
549
    return taskQueue;
1✔
550
  }
551

552
  /**
553
   * @return The options used for the worker.
554
   */
555
  public WorkerOptions getWorkerOptions() {
556
    return workerOptions;
1✔
557
  }
558

559
  /**
560
   * @return endpoint of the nexus service created for the test.
561
   */
562
  public Endpoint getNexusEndpoint() {
563
    return nexusEndpoint;
1✔
564
  }
565

566
  /**
567
   * @return client to the Temporal service used to start and query workflows.
568
   */
569
  public WorkflowClient getWorkflowClient() {
570
    return testEnvironment.getWorkflowClient();
1✔
571
  }
572

573
  /**
574
   * @return client to the Temporal service used to start standalone activities.
575
   */
576
  public ActivityClient getActivityClient() {
577
    return testEnvironment.getActivityClient();
1✔
578
  }
579

580
  /**
581
   * @return stubs connected to the test server (in-memory or external)
582
   */
583
  public WorkflowServiceStubs getWorkflowServiceStubs() {
584
    return testEnvironment.getWorkflowServiceStubs();
1✔
585
  }
586

587
  /**
588
   * @return blockingStub
589
   */
590
  public WorkflowServiceGrpc.WorkflowServiceBlockingStub blockingStub() {
591
    return getWorkflowServiceStubs().blockingStub();
×
592
  }
593

594
  /**
595
   * @return tracer.
596
   */
597
  public <T extends WorkerInterceptor> T getInterceptor(Class<T> type) {
598
    if (workerFactoryOptions.getWorkerInterceptors() != null) {
1!
599
      for (WorkerInterceptor interceptor : workerFactoryOptions.getWorkerInterceptors()) {
1✔
600
        if (type.isInstance(interceptor)) {
1✔
601
          return type.cast(interceptor);
1✔
602
        }
603
      }
604
    }
605
    return null;
1✔
606
  }
607

608
  /**
609
   * @return workflow execution history
610
   * @deprecated use {@link WorkflowClient#fetchHistory(String, String)}. To obtain a WorkflowClient
611
   *     use {@link #getWorkflowClient()}
612
   */
613
  @Deprecated
614
  public History getHistory(@Nonnull WorkflowExecution execution) {
615
    return testEnvironment.getWorkflowExecutionHistory(execution).getHistory();
×
616
  }
617

618
  /**
619
   * @return name of the task queue that test worker is polling.
620
   * @deprecated use {@link WorkflowClient#fetchHistory(String, String)}. To obtain a WorkflowClient
621
   *     use {@link #getWorkflowClient()}
622
   */
623
  @Deprecated
624
  public History getWorkflowExecutionHistory(WorkflowExecution execution) {
625
    return testEnvironment.getWorkflowExecutionHistory(execution).getHistory();
×
626
  }
627

628
  /**
629
   * This worker listens to the default task queue which is obtainable via the {@link
630
   * #getTaskQueue()} method.
631
   *
632
   * @return the default worker created for each test method.
633
   */
634
  public Worker getWorker() {
635
    return testEnvironment.getWorkerFactory().getWorker(getTaskQueue());
1✔
636
  }
637

638
  public WorkerFactoryOptions getWorkerFactoryOptions() {
639
    return workerFactoryOptions;
1✔
640
  }
641

642
  public <T> T newWorkflowStub(Class<T> workflow) {
643
    return getWorkflowClient()
1✔
644
        .newWorkflowStub(workflow, newWorkflowOptionsForTaskQueue(getTaskQueue()));
1✔
645
  }
646

647
  public WorkflowStub newUntypedWorkflowStub(String workflow) {
648
    return getWorkflowClient()
1✔
649
        .newUntypedWorkflowStub(workflow, newWorkflowOptionsForTaskQueue(getTaskQueue()));
1✔
650
  }
651

652
  /**
653
   * @return A unique string containing the test name appended to the task queue used by the test
654
   *     worker. Can be used for other test-specific naming.
655
   */
656
  public String getUniquePostfix() {
657
    return uniquePostfix;
1✔
658
  }
659

660
  private static WorkflowOptions newWorkflowOptionsForTaskQueue(String taskQueue) {
661
    return WorkflowOptions.newBuilder().setTaskQueue(taskQueue).build();
1✔
662
  }
663
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc