diff --git a/core/modules/layout_builder/layout_builder.services.yml b/core/modules/layout_builder/layout_builder.services.yml
index 778a6d5fa60ce8ef3ec92e025bf5d1ae7d19e39c..a648eef6b1b867c2866e19ad2b272588c376b2d1 100644
--- a/core/modules/layout_builder/layout_builder.services.yml
+++ b/core/modules/layout_builder/layout_builder.services.yml
@@ -31,3 +31,8 @@ services:
   layout_builder.sample_entity_generator:
     class: Drupal\layout_builder\Entity\LayoutBuilderSampleEntityGenerator
     arguments: ['@tempstore.shared', '@entity_type.manager']
+  layout_builder.render_block_component_subscriber:
+    class: Drupal\layout_builder\EventSubscriber\BlockComponentRenderArray
+    arguments: ['@current_user']
+    tags:
+      - { name: event_subscriber }
diff --git a/core/modules/layout_builder/src/Event/SectionComponentBuildRenderArrayEvent.php b/core/modules/layout_builder/src/Event/SectionComponentBuildRenderArrayEvent.php
new file mode 100644
index 0000000000000000000000000000000000000000..9047e6e9dc52efc51f06ef8d03f92e9cb3d09ee2
--- /dev/null
+++ b/core/modules/layout_builder/src/Event/SectionComponentBuildRenderArrayEvent.php
@@ -0,0 +1,138 @@
+<?php
+
+namespace Drupal\layout_builder\Event;
+
+use Drupal\Core\Cache\CacheableResponseTrait;
+use Drupal\layout_builder\SectionComponent;
+use Symfony\Component\EventDispatcher\Event;
+
+/**
+ * Event fired when a section component's render array is being built.
+ *
+ * Subscribers to this event should manipulate the cacheability object and the
+ * build array in this event.
+ *
+ * @see \Drupal\layout_builder\LayoutBuilderEvents::SECTION_COMPONENT_BUILD_RENDER_ARRAY
+ *
+ * @internal
+ *   Layout Builder is currently experimental and should only be leveraged by
+ *   experimental modules and development releases of contributed modules.
+ *   See https://www.drupal.org/core/experimental for more information.
+ */
+class SectionComponentBuildRenderArrayEvent extends Event {
+
+  use CacheableResponseTrait;
+
+  /**
+   * The section component whose render array is being built.
+   *
+   * @var \Drupal\layout_builder\SectionComponent
+   */
+  protected $component;
+
+  /**
+   * The available contexts.
+   *
+   * @var \Drupal\Core\Plugin\Context\ContextInterface[]
+   */
+  protected $contexts;
+
+  /**
+   * The plugin for the section component being built.
+   *
+   * @var \Drupal\Component\Plugin\PluginInspectionInterface
+   */
+  protected $plugin;
+
+  /**
+   * Whether the component is in preview mode or not.
+   *
+   * @var bool
+   */
+  protected $inPreview;
+
+  /**
+   * The render array built by the event subscribers.
+   *
+   * @var array
+   */
+  protected $build = [];
+
+  /**
+   * Creates a new SectionComponentBuildRenderArrayEvent object.
+   *
+   * @param \Drupal\layout_builder\SectionComponent $component
+   *   The section component whose render array is being built.
+   * @param \Drupal\Core\Plugin\Context\ContextInterface[] $contexts
+   *   The available contexts.
+   * @param bool $in_preview
+   *   (optional) Whether the component is in preview mode or not.
+   */
+  public function __construct(SectionComponent $component, array $contexts, $in_preview = FALSE) {
+    $this->component = $component;
+    $this->contexts = $contexts;
+    $this->plugin = $component->getPlugin($contexts);
+    $this->inPreview = $in_preview;
+  }
+
+  /**
+   * Get the section component whose render array is being built.
+   *
+   * @return \Drupal\layout_builder\SectionComponent
+   *   The section component whose render array is being built.
+   */
+  public function getComponent() {
+    return $this->component;
+  }
+
+  /**
+   * Get the available contexts.
+   *
+   * @return array|\Drupal\Core\Plugin\Context\ContextInterface[]
+   *   The available contexts.
+   */
+  public function getContexts() {
+    return $this->contexts;
+  }
+
+  /**
+   * Get the plugin for the section component being built.
+   *
+   * @return \Drupal\Component\Plugin\PluginInspectionInterface
+   *   The plugin for the section component being built.
+   */
+  public function getPlugin() {
+    return $this->plugin;
+  }
+
+  /**
+   * Determine if the component is in preview mode.
+   *
+   * @return bool
+   *   Whether the component is in preview mode or not.
+   */
+  public function inPreview() {
+    return $this->inPreview;
+  }
+
+  /**
+   * Get the render array in its current state.
+   *
+   * @return array
+   *   The render array built by the event subscribers.
+   */
+  public function getBuild() {
+    return $this->build;
+  }
+
+  /**
+   * Set the render array.
+   *
+   * @param array $build
+   *   A render array.
+   */
+  public function setBuild(array $build) {
+    $this->build = $build;
+  }
+
+}
diff --git a/core/modules/layout_builder/src/EventSubscriber/BlockComponentRenderArray.php b/core/modules/layout_builder/src/EventSubscriber/BlockComponentRenderArray.php
new file mode 100644
index 0000000000000000000000000000000000000000..181ed8229b6cc523f54c4b1b02451658986bb0da
--- /dev/null
+++ b/core/modules/layout_builder/src/EventSubscriber/BlockComponentRenderArray.php
@@ -0,0 +1,85 @@
+<?php
+
+namespace Drupal\layout_builder\EventSubscriber;
+
+use Drupal\Core\Access\AccessResult;
+use Drupal\Core\Block\BlockPluginInterface;
+use Drupal\Core\Session\AccountInterface;
+use Drupal\layout_builder\Event\SectionComponentBuildRenderArrayEvent;
+use Drupal\layout_builder\LayoutBuilderEvents;
+use Symfony\Component\EventDispatcher\EventSubscriberInterface;
+
+/**
+ * Builds render arrays and handles access for all block components.
+ *
+ * @internal
+ *   Layout Builder is currently experimental and should only be leveraged by
+ *   experimental modules and development releases of contributed modules.
+ *   See https://www.drupal.org/core/experimental for more information.
+ */
+class BlockComponentRenderArray implements EventSubscriberInterface {
+
+  /**
+   * The current user.
+   *
+   * @var \Drupal\Core\Session\AccountInterface
+   */
+  protected $currentUser;
+
+  /**
+   * Creates a BlockComponentRenderArray object.
+   *
+   * @param \Drupal\Core\Session\AccountInterface $current_user
+   *   The current user.
+   */
+  public function __construct(AccountInterface $current_user) {
+    $this->currentUser = $current_user;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function getSubscribedEvents() {
+    $events[LayoutBuilderEvents::SECTION_COMPONENT_BUILD_RENDER_ARRAY] = ['onBuildRender', 100];
+    return $events;
+  }
+
+  /**
+   * Builds render arrays for block plugins and sets it on the event.
+   *
+   * @param \Drupal\layout_builder\Event\SectionComponentBuildRenderArrayEvent $event
+   *   The section component render event.
+   */
+  public function onBuildRender(SectionComponentBuildRenderArrayEvent $event) {
+    $block = $event->getPlugin();
+    if (!$block instanceof BlockPluginInterface) {
+      return;
+    }
+
+    // Only check access if the component is not being previewed.
+    if ($event->inPreview()) {
+      $access = AccessResult::allowed()->setCacheMaxAge(0);
+    }
+    else {
+      $access = $block->access($this->currentUser, TRUE);
+    }
+
+    $event->addCacheableDependency($access);
+    if ($access->isAllowed()) {
+      $event->addCacheableDependency($block);
+
+      $build = [
+        // @todo Move this to BlockBase in https://www.drupal.org/node/2931040.
+        '#theme' => 'block',
+        '#configuration' => $block->getConfiguration(),
+        '#plugin_id' => $block->getPluginId(),
+        '#base_plugin_id' => $block->getBaseId(),
+        '#derivative_plugin_id' => $block->getDerivativeId(),
+        '#weight' => $event->getComponent()->getWeight(),
+        'content' => $block->build(),
+      ];
+      $event->setBuild($build);
+    }
+  }
+
+}
diff --git a/core/modules/layout_builder/src/LayoutBuilderEvents.php b/core/modules/layout_builder/src/LayoutBuilderEvents.php
new file mode 100644
index 0000000000000000000000000000000000000000..b680f98d341b45e9d73edcc82d2d2619dea3fdd4
--- /dev/null
+++ b/core/modules/layout_builder/src/LayoutBuilderEvents.php
@@ -0,0 +1,34 @@
+<?php
+
+namespace Drupal\layout_builder;
+
+/**
+ * Defines events for the layout_builder module.
+ *
+ * @see \Drupal\layout_builder\Event\SectionComponentBuildRenderArrayEvent
+ *
+ * @internal
+ *   Layout Builder is currently experimental and should only be leveraged by
+ *   experimental modules and development releases of contributed modules.
+ *   See https://www.drupal.org/core/experimental for more information.
+ */
+final class LayoutBuilderEvents {
+
+  /**
+   * Name of the event fired when a component's render array is built.
+   *
+   * This event allows modules to collaborate on creating the render array of
+   * the SectionComponent object. The event listener method receives a
+   * \Drupal\layout_builder\Event\SectionComponentBuildRenderArrayEvent
+   * instance.
+   *
+   * @Event
+   *
+   * @see \Drupal\layout_builder\Event\SectionComponentBuildRenderArrayEvent
+   * @see \Drupal\layout_builder\SectionComponent::toRenderArray()
+   *
+   * @var string
+   */
+  const SECTION_COMPONENT_BUILD_RENDER_ARRAY = 'section_component.build.render_array';
+
+}
diff --git a/core/modules/layout_builder/src/SectionComponent.php b/core/modules/layout_builder/src/SectionComponent.php
index 6c08fb3aeb7df5a1bd0fe4d1a96ec856056f2dfe..081d982f054b4dd50a12876a349acca5df6c0fa1 100644
--- a/core/modules/layout_builder/src/SectionComponent.php
+++ b/core/modules/layout_builder/src/SectionComponent.php
@@ -3,10 +3,8 @@
 namespace Drupal\layout_builder;
 
 use Drupal\Component\Plugin\Exception\PluginException;
-use Drupal\Core\Access\AccessResult;
-use Drupal\Core\Block\BlockPluginInterface;
-use Drupal\Core\Cache\CacheableMetadata;
 use Drupal\Core\Plugin\ContextAwarePluginInterface;
+use Drupal\layout_builder\Event\SectionComponentBuildRenderArrayEvent;
 
 /**
  * Provides a value object for a section component.
@@ -98,37 +96,10 @@ public function __construct($uuid, $region, array $configuration = [], array $ad
    *   A renderable array representing the content of the component.
    */
   public function toRenderArray(array $contexts = [], $in_preview = FALSE) {
-    $output = [];
-
-    $plugin = $this->getPlugin($contexts);
-    // @todo Figure out the best way to unify fields and blocks and components
-    //   in https://www.drupal.org/node/1875974.
-    if ($plugin instanceof BlockPluginInterface) {
-      $cacheability = CacheableMetadata::createFromObject($plugin);
-
-      // Only check access if the component is not being previewed.
-      if ($in_preview) {
-        $access = AccessResult::allowed()->setCacheMaxAge(0);
-      }
-      else {
-        $access = $plugin->access($this->currentUser(), TRUE);
-      }
-
-      $cacheability->addCacheableDependency($access);
-      if ($access->isAllowed()) {
-        // @todo Move this to BlockBase in https://www.drupal.org/node/2931040.
-        $output = [
-          '#theme' => 'block',
-          '#configuration' => $plugin->getConfiguration(),
-          '#plugin_id' => $plugin->getPluginId(),
-          '#base_plugin_id' => $plugin->getBaseId(),
-          '#derivative_plugin_id' => $plugin->getDerivativeId(),
-          '#weight' => $this->getWeight(),
-          'content' => $plugin->build(),
-        ];
-      }
-      $cacheability->applyTo($output);
-    }
+    $event = new SectionComponentBuildRenderArrayEvent($this, $contexts, $in_preview);
+    $this->eventDispatcher()->dispatch(LayoutBuilderEvents::SECTION_COMPONENT_BUILD_RENDER_ARRAY, $event);
+    $output = $event->getBuild();
+    $event->getCacheableMetadata()->applyTo($output);
     return $output;
   }
 
@@ -293,6 +264,8 @@ public function getPlugin(array $contexts = []) {
    *   The plugin manager.
    */
   protected function pluginManager() {
+    // @todo Figure out the best way to unify fields and blocks and components
+    //   in https://www.drupal.org/node/1875974.
     return \Drupal::service('plugin.manager.block');
   }
 
@@ -307,13 +280,13 @@ protected function contextHandler() {
   }
 
   /**
-   * Wraps the current user.
+   * Wraps the event dispatcher.
    *
-   * @return \Drupal\Core\Session\AccountInterface
-   *   The current user.
+   * @return \Symfony\Component\EventDispatcher\EventDispatcherInterface
+   *   The event dispatcher.
    */
-  protected function currentUser() {
-    return \Drupal::currentUser();
+  protected function eventDispatcher() {
+    return \Drupal::service('event_dispatcher');
   }
 
   /**
diff --git a/core/modules/layout_builder/tests/src/Unit/BlockComponentRenderArrayTest.php b/core/modules/layout_builder/tests/src/Unit/BlockComponentRenderArrayTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..6571a8ff1a6d2130d27aa3bdfdfa98fa2e1cd91b
--- /dev/null
+++ b/core/modules/layout_builder/tests/src/Unit/BlockComponentRenderArrayTest.php
@@ -0,0 +1,222 @@
+<?php
+
+namespace Drupal\Tests\layout_builder\Unit;
+
+use Drupal\Core\Access\AccessResult;
+use Drupal\Core\Block\BlockManagerInterface;
+use Drupal\Core\Block\BlockPluginInterface;
+use Drupal\Core\Cache\Cache;
+use Drupal\Core\DependencyInjection\ContainerBuilder;
+use Drupal\Core\Session\AccountInterface;
+use Drupal\layout_builder\Event\SectionComponentBuildRenderArrayEvent;
+use Drupal\layout_builder\EventSubscriber\BlockComponentRenderArray;
+use Drupal\layout_builder\SectionComponent;
+use Drupal\Tests\UnitTestCase;
+
+/**
+ * @coversDefaultClass \Drupal\layout_builder\EventSubscriber\BlockComponentRenderArray
+ * @group layout_builder
+ */
+class BlockComponentRenderArrayTest extends UnitTestCase {
+
+  /**
+   * The current user.
+   *
+   * @var \Drupal\Core\Session\AccountInterface
+   */
+  protected $account;
+
+  /**
+   * The block plugin manager.
+   *
+   * @var \Drupal\Core\Block\BlockManagerInterface
+   */
+  protected $blockManager;
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+
+    $this->blockManager = $this->prophesize(BlockManagerInterface::class);
+    $this->account = $this->prophesize(AccountInterface::class);
+
+    $container = new ContainerBuilder();
+    $container->set('plugin.manager.block', $this->blockManager->reveal());
+    \Drupal::setContainer($container);
+  }
+
+  /**
+   * @covers ::onBuildRender
+   */
+  public function testOnBuildRender() {
+    $block = $this->prophesize(BlockPluginInterface::class);
+    $access_result = AccessResult::allowed();
+    $block->access($this->account->reveal(), TRUE)->willReturn($access_result)->shouldBeCalled();
+    $block->getCacheContexts()->willReturn([]);
+    $block->getCacheTags()->willReturn(['test']);
+    $block->getCacheMaxAge()->willReturn(Cache::PERMANENT);
+    $block->getConfiguration()->willReturn([]);
+    $block->getPluginId()->willReturn('block_plugin_id');
+    $block->getBaseId()->willReturn('block_plugin_id');
+    $block->getDerivativeId()->willReturn(NULL);
+
+    $block_content = ['#markup' => 'The block content.'];
+    $block->build()->willReturn($block_content);
+    $this->blockManager->createInstance('some_block_id', ['id' => 'some_block_id'])->willReturn($block->reveal());
+
+    $component = new SectionComponent('some-uuid', 'some-region', ['id' => 'some_block_id']);
+    $contexts = [];
+    $in_preview = FALSE;
+    $event = new SectionComponentBuildRenderArrayEvent($component, $contexts, $in_preview);
+
+    $subscriber = new BlockComponentRenderArray($this->account->reveal());
+
+    $expected_build = [
+      '#theme' => 'block',
+      '#weight' => 0,
+      '#configuration' => [],
+      '#plugin_id' => 'block_plugin_id',
+      '#base_plugin_id' => 'block_plugin_id',
+      '#derivative_plugin_id' => NULL,
+      'content' => $block_content,
+    ];
+
+    $expected_cache = $expected_build + [
+      '#cache' => [
+        'contexts' => [],
+        'tags' => ['test'],
+        'max-age' => -1,
+      ],
+    ];
+
+    $subscriber->onBuildRender($event);
+    $result = $event->getBuild();
+    $this->assertEquals($expected_build, $result);
+    $event->getCacheableMetadata()->applyTo($result);
+    $this->assertEquals($expected_cache, $result);
+  }
+
+  /**
+   * @covers ::onBuildRender
+   */
+  public function testOnBuildRenderDenied() {
+    $block = $this->prophesize(BlockPluginInterface::class);
+    $access_result = AccessResult::forbidden();
+    $block->access($this->account->reveal(), TRUE)->willReturn($access_result)->shouldBeCalled();
+    $block->getCacheContexts()->shouldNotBeCalled();
+    $block->getCacheTags()->shouldNotBeCalled();
+    $block->getCacheMaxAge()->shouldNotBeCalled();
+    $block->getConfiguration()->shouldNotBeCalled();
+    $block->getPluginId()->shouldNotBeCalled();
+    $block->getBaseId()->shouldNotBeCalled();
+    $block->getDerivativeId()->shouldNotBeCalled();
+
+    $block_content = ['#markup' => 'The block content.'];
+    $block->build()->willReturn($block_content);
+    $this->blockManager->createInstance('some_block_id', ['id' => 'some_block_id'])->willReturn($block->reveal());
+
+    $component = new SectionComponent('some-uuid', 'some-region', ['id' => 'some_block_id']);
+    $contexts = [];
+    $in_preview = FALSE;
+    $event = new SectionComponentBuildRenderArrayEvent($component, $contexts, $in_preview);
+
+    $subscriber = new BlockComponentRenderArray($this->account->reveal());
+
+    $expected_build = [];
+    $expected_cache = [
+      '#cache' => [
+        'contexts' => [],
+        'tags' => [],
+        'max-age' => -1,
+      ],
+    ];
+
+    $subscriber->onBuildRender($event);
+    $result = $event->getBuild();
+    $this->assertEquals($expected_build, $result);
+    $event->getCacheableMetadata()->applyTo($result);
+    $this->assertEquals($expected_cache, $result);
+  }
+
+  /**
+   * @covers ::onBuildRender
+   */
+  public function testOnBuildRenderInPreview() {
+    $block = $this->prophesize(BlockPluginInterface::class);
+    $block->access($this->account->reveal(), TRUE)->shouldNotBeCalled();
+    $block->getCacheContexts()->willReturn([]);
+    $block->getCacheTags()->willReturn(['test']);
+    $block->getCacheMaxAge()->willReturn(Cache::PERMANENT);
+    $block->getConfiguration()->willReturn([]);
+    $block->getPluginId()->willReturn('block_plugin_id');
+    $block->getBaseId()->willReturn('block_plugin_id');
+    $block->getDerivativeId()->willReturn(NULL);
+
+    $block_content = ['#markup' => 'The block content.'];
+    $block->build()->willReturn($block_content);
+    $this->blockManager->createInstance('some_block_id', ['id' => 'some_block_id'])->willReturn($block->reveal());
+
+    $component = new SectionComponent('some-uuid', 'some-region', ['id' => 'some_block_id']);
+    $contexts = [];
+    $in_preview = TRUE;
+    $event = new SectionComponentBuildRenderArrayEvent($component, $contexts, $in_preview);
+
+    $subscriber = new BlockComponentRenderArray($this->account->reveal());
+
+    $expected_build = [
+      '#theme' => 'block',
+      '#weight' => 0,
+      '#configuration' => [],
+      '#plugin_id' => 'block_plugin_id',
+      '#base_plugin_id' => 'block_plugin_id',
+      '#derivative_plugin_id' => NULL,
+      'content' => $block_content,
+    ];
+
+    $expected_cache = $expected_build + [
+      '#cache' => [
+        'contexts' => [],
+        'tags' => ['test'],
+        'max-age' => 0,
+      ],
+    ];
+
+    $subscriber->onBuildRender($event);
+    $result = $event->getBuild();
+    $this->assertEquals($expected_build, $result);
+    $event->getCacheableMetadata()->applyTo($result);
+    $this->assertEquals($expected_cache, $result);
+  }
+
+  /**
+   * @covers ::onBuildRender
+   */
+  public function testOnBuildRenderNoBlock() {
+    $this->blockManager->createInstance('some_block_id', ['id' => 'some_block_id'])->willReturn(NULL);
+
+    $component = new SectionComponent('some-uuid', 'some-region', ['id' => 'some_block_id']);
+    $contexts = [];
+    $in_preview = FALSE;
+    $event = new SectionComponentBuildRenderArrayEvent($component, $contexts, $in_preview);
+
+    $subscriber = new BlockComponentRenderArray($this->account->reveal());
+
+    $expected_build = [];
+    $expected_cache = [
+      '#cache' => [
+        'contexts' => [],
+        'tags' => [],
+        'max-age' => -1,
+      ],
+    ];
+
+    $subscriber->onBuildRender($event);
+    $result = $event->getBuild();
+    $this->assertEquals($expected_build, $result);
+    $event->getCacheableMetadata()->applyTo($result);
+    $this->assertEquals($expected_cache, $result);
+  }
+
+}
diff --git a/core/modules/layout_builder/tests/src/Unit/SectionComponentTest.php b/core/modules/layout_builder/tests/src/Unit/SectionComponentTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..48a24778c1ab83160649f1298188432f1a0352a3
--- /dev/null
+++ b/core/modules/layout_builder/tests/src/Unit/SectionComponentTest.php
@@ -0,0 +1,71 @@
+<?php
+
+namespace Drupal\Tests\layout_builder\Unit;
+
+use Drupal\Core\Block\BlockManagerInterface;
+use Drupal\Core\Block\BlockPluginInterface;
+use Drupal\Core\DependencyInjection\ContainerBuilder;
+use Drupal\Core\Layout\LayoutInterface;
+use Drupal\Core\Layout\LayoutPluginManagerInterface;
+use Drupal\layout_builder\Event\SectionComponentBuildRenderArrayEvent;
+use Drupal\layout_builder\LayoutBuilderEvents;
+use Drupal\layout_builder\SectionComponent;
+use Drupal\Tests\UnitTestCase;
+use Prophecy\Argument;
+use Symfony\Component\EventDispatcher\EventDispatcherInterface;
+
+/**
+ * @coversDefaultClass \Drupal\layout_builder\SectionComponent
+ * @group layout_builder
+ */
+class SectionComponentTest extends UnitTestCase {
+
+  /**
+   * @covers ::toRenderArray
+   */
+  public function testToRenderArray() {
+    $existing_block = $this->prophesize(BlockPluginInterface::class);
+    $existing_block->getPluginId()->willReturn('block_plugin_id');
+
+    $block_manager = $this->prophesize(BlockManagerInterface::class);
+    $block_manager->createInstance('some_block_id', ['id' => 'some_block_id'])->willReturn($existing_block->reveal());
+
+    // Imitate an event subscriber by setting a resulting build on the event.
+    $event_dispatcher = $this->prophesize(EventDispatcherInterface::class);
+    $event_dispatcher
+      ->dispatch(LayoutBuilderEvents::SECTION_COMPONENT_BUILD_RENDER_ARRAY, Argument::type(SectionComponentBuildRenderArrayEvent::class))
+      ->shouldBeCalled()
+      ->will(function ($args) {
+        /** @var \Drupal\layout_builder\Event\SectionComponentBuildRenderArrayEvent $event */
+        $event = $args[1];
+        $event->setBuild(['#markup' => $event->getPlugin()->getPluginId()]);
+        return;
+      });
+
+    $layout_plugin = $this->prophesize(LayoutInterface::class);
+    $layout_plugin->build(Argument::type('array'))->willReturnArgument(0);
+
+    $layout_manager = $this->prophesize(LayoutPluginManagerInterface::class);
+    $layout_manager->createInstance('layout_onecol', [])->willReturn($layout_plugin->reveal());
+
+    $container = new ContainerBuilder();
+    $container->set('plugin.manager.block', $block_manager->reveal());
+    $container->set('event_dispatcher', $event_dispatcher->reveal());
+    $container->set('plugin.manager.core.layout', $layout_manager->reveal());
+    \Drupal::setContainer($container);
+
+    $expected = [
+      '#cache' => [
+        'contexts' => [],
+        'tags' => [],
+        'max-age' => -1,
+      ],
+      '#markup' => 'block_plugin_id',
+    ];
+
+    $component = new SectionComponent('some-uuid', 'some-region', ['id' => 'some_block_id']);
+    $result = $component->toRenderArray();
+    $this->assertEquals($expected, $result);
+  }
+
+}
diff --git a/core/modules/layout_builder/tests/src/Unit/SectionRenderTest.php b/core/modules/layout_builder/tests/src/Unit/SectionRenderTest.php
index ed7dfd202f9f58530128641e73e4f87cba5bdc42..079a220a450e78ee968406e0f800ee6811dd4d17 100644
--- a/core/modules/layout_builder/tests/src/Unit/SectionRenderTest.php
+++ b/core/modules/layout_builder/tests/src/Unit/SectionRenderTest.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\Tests\layout_builder\Unit;
 
+use Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher;
 use Drupal\Component\Plugin\Exception\PluginException;
 use Drupal\Core\Access\AccessResult;
 use Drupal\Core\Block\BlockManagerInterface;
@@ -15,6 +16,7 @@
 use Drupal\Core\Plugin\Context\ContextRepositoryInterface;
 use Drupal\Core\Plugin\ContextAwarePluginInterface;
 use Drupal\Core\Session\AccountInterface;
+use Drupal\layout_builder\EventSubscriber\BlockComponentRenderArray;
 use Drupal\layout_builder\Section;
 use Drupal\layout_builder\SectionComponent;
 use Drupal\Tests\UnitTestCase;
@@ -54,17 +56,29 @@ class SectionRenderTest extends UnitTestCase {
    */
   protected $contextRepository;
 
+  /**
+   * The event dispatcher.
+   *
+   * @var \Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher
+   */
+  protected $eventDispatcher;
+
   /**
    * {@inheritdoc}
    */
   protected function setUp() {
     parent::setUp();
 
-    $this->account = $this->prophesize(AccountInterface::class);
     $layout_plugin_manager = $this->prophesize(LayoutPluginManagerInterface::class);
     $this->blockManager = $this->prophesize(BlockManagerInterface::class);
     $this->contextHandler = $this->prophesize(ContextHandlerInterface::class);
     $this->contextRepository = $this->prophesize(ContextRepositoryInterface::class);
+    // @todo Refactor this into some better tests in https://www.drupal.org/node/2942605.
+    $this->eventDispatcher = (new \ReflectionClass(ContainerAwareEventDispatcher::class))->newInstanceWithoutConstructor();
+
+    $this->account = $this->prophesize(AccountInterface::class);
+    $subscriber = new BlockComponentRenderArray($this->account->reveal());
+    $this->eventDispatcher->addSubscriber($subscriber);
 
     $layout = $this->prophesize(LayoutInterface::class);
     $layout->getPluginDefinition()->willReturn(new LayoutDefinition([]));
@@ -77,6 +91,7 @@ protected function setUp() {
     $container->set('plugin.manager.core.layout', $layout_plugin_manager->reveal());
     $container->set('context.handler', $this->contextHandler->reveal());
     $container->set('context.repository', $this->contextRepository->reveal());
+    $container->set('event_dispatcher', $this->eventDispatcher);
     \Drupal::setContainer($container);
   }