public static <InputT, OutputT> DoFnInvoker<InputT, OutputT> invokerFor(
      DoFn<InputT, OutputT> fn) {
    return ByteBuddyDoFnInvokerFactory.only().newByteBuddyInvoker(fn);
  }
@Test
  public void testDoFnWithStartBundleSetupTeardown() throws Exception {
    when(mockArgumentProvider.pipelineOptions()).thenReturn(mockOptions);
    when(mockArgumentProvider.startBundleContext(any(DoFn.class)))
        .thenReturn(mockStartBundleContext);
    when(mockArgumentProvider.finishBundleContext(any(DoFn.class)))
        .thenReturn(mockFinishBundleContext);
    class MockFn extends DoFn<String, String> {
      @ProcessElement
      public void processElement(ProcessContext c) {}

      @StartBundle
      public void startBundle(StartBundleContext c) {}

      @FinishBundle
      public void finishBundle(FinishBundleContext c) {}

      @Setup
      public void before(PipelineOptions options) {}

      @Teardown
      public void after() {}
    }

    MockFn fn = mock(MockFn.class);

    DoFnInvoker<String, String> invoker = DoFnInvokers.invokerFor(fn);
    invoker.invokeSetup(mockArgumentProvider);
    invoker.invokeStartBundle(mockArgumentProvider);
    invoker.invokeFinishBundle(mockArgumentProvider);
    invoker.invokeTeardown();
    verify(fn).before(mockOptions);
    verify(fn).startBundle(mockStartBundleContext);
    verify(fn).finishBundle(mockFinishBundleContext);
    verify(fn).after();
  }