diff --git a/modules/stanford_person/modules/stanford_person_importer/src/Config/ConfigOverrides.php b/modules/stanford_person/modules/stanford_person_importer/src/Config/ConfigOverrides.php
index 525b101d..79447cce 100644
--- a/modules/stanford_person/modules/stanford_person_importer/src/Config/ConfigOverrides.php
+++ b/modules/stanford_person/modules/stanford_person_importer/src/Config/ConfigOverrides.php
@@ -4,12 +4,8 @@
 
 use Drupal\config_pages\ConfigPagesLoaderServiceInterface;
 use Drupal\Core\Cache\CacheableMetadata;
-use Drupal\Core\Config\ConfigFactoryInterface;
 use Drupal\Core\Config\ConfigFactoryOverrideInterface;
 use Drupal\Core\Config\StorageInterface;
-use Drupal\Core\Entity\EntityTypeManagerInterface;
-use Drupal\Core\Url;
-use Drupal\stanford_person_importer\CapInterface;
 
 /**
  * Configuration overrides for stanford person importer migration entity.
@@ -18,11 +14,6 @@
  */
 class ConfigOverrides implements ConfigFactoryOverrideInterface {
 
-  /**
-   * How many profiles are returned in each url.
-   */
-  const URL_CHUNKS = 15;
-
   /**
    * Config pages loader service.
    *
@@ -30,44 +21,14 @@ class ConfigOverrides implements ConfigFactoryOverrideInterface {
    */
   protected $configPages;
 
-  /**
-   * Entity type manager service.
-   *
-   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
-   */
-  protected $entityTypeManager;
-
-  /**
-   * Cap API service.
-   *
-   * @var \Drupal\stanford_person_importer\CapInterface
-   */
-  protected $cap;
-
-  /**
-   * Config factory service.
-   *
-   * @var \Drupal\Core\Config\ConfigFactoryInterface
-   */
-  protected $configFactory;
-
   /**
    * ConfigOverrides constructor.
    *
    * @param \Drupal\config_pages\ConfigPagesLoaderServiceInterface $config_pages
    *   Config pages loader service.
-   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
-   *   Entity type manager service.
-   * @param \Drupal\stanford_person_importer\CapInterface $cap
-   *   Cap API service.
-   * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
-   *   Config factory service.
    */
-  public function __construct(ConfigPagesLoaderServiceInterface $config_pages, EntityTypeManagerInterface $entity_type_manager, CapInterface $cap, ConfigFactoryInterface $config_factory) {
+  public function __construct(protected ConfigPagesLoaderServiceInterface $config_pages) {
     $this->configPages = $config_pages;
-    $this->entityTypeManager = $entity_type_manager;
-    $this->cap = $cap;
-    $this->configFactory = $config_factory;
   }
 
   /**
@@ -97,156 +58,13 @@ public function getCacheableMetadata($name) {
   public function loadOverrides($names) {
     $overrides = [];
     if (in_array('migrate_plus.migration.su_stanford_person', $names)) {
-      $urls = $this->getImporterUrls();
-
-      if ($urls === NULL) {
-        $overrides['migrate_plus.migration.su_stanford_person']['status'] = FALSE;
-        return $overrides;
-      }
-
-      $overrides['migrate_plus.migration.su_stanford_person']['source']['urls'] = $urls;
+      $overrides['migrate_plus.migration.su_stanford_person']['source']['plugin'] = 'cap_url';
       $overrides['migrate_plus.migration.su_stanford_person']['source']['authentication']['client_id'] = $this->getCapClientId();
       $overrides['migrate_plus.migration.su_stanford_person']['source']['authentication']['client_secret'] = $this->getCapClientSecret();
-    }
-    return $overrides;
-  }
-
-  /**
-   * Get a list of urls for the importer.
-   *
-   * @return array|null
-   *   Array of urls or NULL if any errors occur.
-   */
-  protected function getImporterUrls(): ?array {
-    $urls = &drupal_static('cap_source_urls');
-    if ($urls !== NULL) {
-      return $urls;
-    }
-    try {
-      $this->cap->setClientId($this->getCapClientId());
-      $this->cap->setClientSecret($this->getCapClientSecret());
-
-      $urls = $this->getOrgsUrls();
-      $urls = array_merge($urls, $this->getWorkgroupUrls());
-      $urls = array_merge($urls, $this->getSunetUrls());
-    }
-    catch (\Exception $e) {
-      return NULL;
-    }
-
-    $allowed_fields = $this->getAllowedFields();
-    foreach ($urls as &$url) {
-      $url = Url::fromUri($url);
-      $url->mergeOptions(['query' => ['whitelist' => implode(',', $allowed_fields)]]);
-      $url = $url->toString(TRUE)->getGeneratedUrl();
-    }
-    return $urls;
-  }
-
-  /**
-   * Get a list of the fields from CAP that should be fetched.
-   *
-   * @return string[]
-   *   Array of CAP selectors.
-   */
-  protected function getAllowedFields() {
-    $allowed_fields = $this->configFactory->getEditable('migrate_plus.migration.su_stanford_person')
-      ->getOriginal('source.fields') ?: [];
-    foreach ($allowed_fields as &$field) {
-      $field = $field['selector'];
-      if ($slash_position = strpos($field, '/')) {
-        $field = substr($field, 0, $slash_position);
-      }
-    }
-    return $allowed_fields;
-  }
-
-  /**
-   * Get a list of CAP urls that have an org code specified.
-   *
-   * @return string[]
-   *   List of urls.
-   *
-   * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
-   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
-   */
-  protected function getOrgsUrls() {
-    $org_tids = array_filter($this->configPages->getValue('stanford_person_importer', 'su_person_orgs', [], 'target_id') ?? []);
-    $include_children = (bool) $this->configPages->getValue('stanford_person_importer', 'su_person_child_orgs', 0, 'value');
-
-    // No field values populated.
-    if (empty($org_tids)) {
-      return [];
-    }
-    $org_codes = [];
-
-    // Load the taxonomy term that the field is pointing at and use the org code
-    // field on the term entity.
-    $term_storage = $this->entityTypeManager->getStorage('taxonomy_term');
-    foreach ($org_tids as &$tid) {
-      if ($term = $term_storage->load($tid)) {
-        $org_code = $term->get('su_cap_org_code')
-          ->getString();
-        $org_codes[] = str_replace(' ', '', $org_code);
-      }
-    }
-    return $this->getUrlChunks($this->cap->getOrganizationUrl($org_codes, $include_children));
-  }
-
-  /**
-   * Get a list of CAP urls that have a workgroup filter.
-   *
-   * @return string[]
-   *   List of urls.
-   */
-  protected function getWorkgroupUrls(): array {
-    $workgroups = array_filter($this->configPages->getValue('stanford_person_importer', 'su_person_workgroup', [], 'value') ?? []);
 
-    if ($workgroups) {
-      return $this->getUrlChunks($this->cap->getWorkgroupUrl($workgroups));
+      $overrides['migrate_plus.migration.su_stanford_person']['status'] = $this->getCapClientId() && $this->getCapClientSecret();
     }
-    return [];
-  }
-
-  /**
-   * Get the list of CAP urls for a sunetid filter.
-   *
-   * @return string[]
-   *   List of urls.
-   */
-  protected function getSunetUrls(): array {
-    $sunets = $this->configPages->getValue('stanford_person_importer', 'su_person_sunetid', [], 'value') ?: [];
-
-    $urls = [];
-    foreach (array_chunk($sunets, self::URL_CHUNKS) as $chunk) {
-      $urls[] = $this->cap->getSunetUrl($chunk)->toString(TRUE)->getGeneratedUrl();
-    }
-    return $urls;
-  }
-
-  /**
-   * Break up the url into multiple urls based on the number of results.
-   *
-   * @param \Drupal\Core\Url $url
-   *   Cap API Url.
-   *
-   * @return string[]
-   *   Array of Cap API Urls.
-   */
-  protected function getUrlChunks(Url $url): array {
-    $count = $this->cap->getTotalProfileCount($url);
-    $number_chunks = ceil($count / self::URL_CHUNKS);
-    if ($number_chunks <= 1) {
-      $url->mergeOptions(['query' => ['ps' => self::URL_CHUNKS]]);
-      return [$url->toString(TRUE)->getGeneratedUrl()];
-    }
-
-    $urls = [];
-    for ($i = 1; $i <= $number_chunks; $i++) {
-      $url->mergeOptions(['query' => ['p' => $i, 'ps' => self::URL_CHUNKS]]);
-      $urls[] = $url->toString(TRUE)->getGeneratedUrl();
-    }
-    return $urls;
+    return $overrides;
   }
 
   /**
diff --git a/modules/stanford_person/modules/stanford_person_importer/src/Plugin/migrate/source/CapUrl.php b/modules/stanford_person/modules/stanford_person_importer/src/Plugin/migrate/source/CapUrl.php
new file mode 100644
index 00000000..d3ca2103
--- /dev/null
+++ b/modules/stanford_person/modules/stanford_person_importer/src/Plugin/migrate/source/CapUrl.php
@@ -0,0 +1,207 @@
+<?php
+
+namespace Drupal\stanford_person_importer\Plugin\migrate\source;
+
+use Drupal\config_pages\ConfigPagesLoaderServiceInterface;
+use Drupal\Core\Config\ConfigFactoryInterface;
+use Drupal\Core\Entity\EntityTypeManagerInterface;
+use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
+use Drupal\Core\Url;
+use Drupal\migrate\Plugin\MigrationInterface;
+use Drupal\migrate_plus\Plugin\migrate\source\Url as UrlPlugin;
+use Drupal\stanford_person_importer\CapInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+
+/**
+ * Source plugin for retrieving data via CAP URLs.
+ *
+ * @MigrateSource(
+ *   id = "cap_url"
+ * )
+ */
+class CapUrl extends UrlPlugin implements ContainerFactoryPluginInterface {
+
+  const URL_CHUNKS = 15;
+
+  /**
+   * {@inheritDoc}
+   */
+  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration = NULL) {
+    return new static(
+      $configuration,
+      $plugin_id,
+      $plugin_definition,
+      $migration,
+      $container->get('stanford_person_importer.cap'),
+      $container->get('config_pages.loader'),
+      $container->get('config.factory'),
+      $container->get('entity_type.manager')
+    );
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration, protected CapInterface $cap, protected ConfigPagesLoaderServiceInterface $configPages, protected ConfigFactoryInterface $configFactory, protected EntityTypeManagerInterface $entityTypeManager) {
+    $this->sourceUrls = $this->getImporterUrls();
+    $configuration['urls'] = $this->sourceUrls;
+    parent::__construct($configuration, $plugin_id, $plugin_definition, $migration);
+  }
+
+  /**
+   * Get a list of urls for the importer.
+   *
+   * @return array|null
+   *   Array of urls or NULL if any errors occur.
+   */
+  protected function getImporterUrls(): array {
+    $urls = &drupal_static('cap_source_urls');
+    if ($urls !== NULL) {
+      return $urls;
+    }
+    try {
+      $this->cap->setClientId($this->getCapClientId());
+      $this->cap->setClientSecret($this->getCapClientSecret());
+
+      $urls = $this->getOrgsUrls();
+      $urls = array_merge($urls, $this->getWorkgroupUrls());
+      $urls = array_merge($urls, $this->getSunetUrls());
+    }
+    catch (\Exception $e) {
+      return [];
+    }
+
+    $allowed_fields = $this->getAllowedFields();
+    foreach ($urls as &$url) {
+      $url = Url::fromUri($url);
+      $url->mergeOptions(['query' => ['whitelist' => implode(',', $allowed_fields)]]);
+      $url = $url->toString(TRUE)->getGeneratedUrl();
+    }
+    return $urls;
+  }
+
+  /**
+   * Get a list of the fields from CAP that should be fetched.
+   *
+   * @return string[]
+   *   Array of CAP selectors.
+   */
+  protected function getAllowedFields() {
+    $allowed_fields = $this->configFactory->get('migrate_plus.migration.su_stanford_person')
+      ->get('source.fields') ?: [];
+    foreach ($allowed_fields as &$field) {
+      $field = $field['selector'];
+      if ($slash_position = strpos($field, '/')) {
+        $field = substr($field, 0, $slash_position);
+      }
+    }
+    return $allowed_fields;
+  }
+
+  /**
+   * Get a list of CAP urls that have an org code specified.
+   *
+   * @return string[]
+   *   List of urls.
+   *
+   * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
+   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
+   */
+  protected function getOrgsUrls() {
+    $org_tids = array_filter($this->configPages->getValue('stanford_person_importer', 'su_person_orgs', [], 'target_id') ?? []);
+    $include_children = (bool) $this->configPages->getValue('stanford_person_importer', 'su_person_child_orgs', 0, 'value');
+
+    // No field values populated.
+    if (empty($org_tids)) {
+      return [];
+    }
+    $org_codes = [];
+
+    // Load the taxonomy term that the field is pointing at and use the org code
+    // field on the term entity.
+    $term_storage = $this->entityTypeManager->getStorage('taxonomy_term');
+    foreach ($org_tids as &$tid) {
+      if ($term = $term_storage->load($tid)) {
+        $org_code = $term->get('su_cap_org_code')
+          ->getString();
+        $org_codes[] = str_replace(' ', '', $org_code);
+      }
+    }
+    return $this->getUrlChunks($this->cap->getOrganizationUrl($org_codes, $include_children));
+  }
+
+  /**
+   * Get a list of CAP urls that have a workgroup filter.
+   *
+   * @return string[]
+   *   List of urls.
+   */
+  protected function getWorkgroupUrls(): array {
+    $workgroups = array_filter($this->configPages->getValue('stanford_person_importer', 'su_person_workgroup', [], 'value') ?? []);
+    return $workgroups ? $this->getUrlChunks($this->cap->getWorkgroupUrl($workgroups)) : [];
+  }
+
+  /**
+   * Get the list of CAP urls for a sunetid filter.
+   *
+   * @return string[]
+   *   List of urls.
+   */
+  protected function getSunetUrls(): array {
+    $sunets = $this->configPages->getValue('stanford_person_importer', 'su_person_sunetid', [], 'value') ?: [];
+
+    $urls = [];
+    foreach (array_chunk($sunets, self::URL_CHUNKS) as $chunk) {
+      $urls[] = $this->cap->getSunetUrl($chunk)
+        ->toString(TRUE)
+        ->getGeneratedUrl();
+    }
+    return $urls;
+  }
+
+  /**
+   * Break up the url into multiple urls based on the number of results.
+   *
+   * @param \Drupal\Core\Url $url
+   *   Cap API Url.
+   *
+   * @return string[]
+   *   Array of Cap API Urls.
+   */
+  protected function getUrlChunks(Url $url): array {
+    $count = $this->cap->getTotalProfileCount($url);
+    $number_chunks = ceil($count / self::URL_CHUNKS);
+    if ($number_chunks <= 1) {
+      $url->mergeOptions(['query' => ['ps' => self::URL_CHUNKS]]);
+      return [$url->toString(TRUE)->getGeneratedUrl()];
+    }
+
+    $urls = [];
+    for ($i = 1; $i <= $number_chunks; $i++) {
+      $url->mergeOptions(['query' => ['p' => $i, 'ps' => self::URL_CHUNKS]]);
+      $urls[] = $url->toString(TRUE)->getGeneratedUrl();
+    }
+    return $urls;
+  }
+
+  /**
+   * Get the username from the config pages field.
+   *
+   * @return string
+   *   Client ID string.
+   */
+  protected function getCapClientId(): string {
+    return $this->configPages->getValue('stanford_person_importer', 'su_person_cap_username', 0, 'value') ?? '';
+  }
+
+  /**
+   * Get the password from the config pages field.
+   *
+   * @return string
+   *   Client secret string.
+   */
+  protected function getCapClientSecret(): string {
+    return $this->configPages->getValue('stanford_person_importer', 'su_person_cap_password', 0, 'value') ?? '';
+  }
+
+}
diff --git a/modules/stanford_person/modules/stanford_person_importer/tests/src/Unit/Config/ConfigOverridesTest.php b/modules/stanford_person/modules/stanford_person_importer/tests/src/Unit/Config/ConfigOverridesTest.php
index fb31dc07..4d76d3cc 100644
--- a/modules/stanford_person/modules/stanford_person_importer/tests/src/Unit/Config/ConfigOverridesTest.php
+++ b/modules/stanford_person/modules/stanford_person_importer/tests/src/Unit/Config/ConfigOverridesTest.php
@@ -106,8 +106,6 @@ protected function getCapService() {
       ->willReturn(Url::fromUri('http://localhost.orgs'));
     $cap->method('getWorkgroupUrl')
       ->willReturn(Url::fromUri('http://localhost.workgroup'));
-    $cap->method('getSunetUrl')
-      ->will($this->returnCallback([$this, 'getSunetUrlCallback']));
 
     return $cap;
   }
@@ -127,13 +125,12 @@ public function testBasicMethods() {
   }
 
   /**
-   * Test the config overrides when theres no urls.
+   * Test the config overrides when there's no urls.
    */
   public function testEmptyConfigOverrides() {
     $overrides = $this->configOverrides->loadOverrides(['migrate_plus.migration.su_stanford_person']);
     $this->assertEmpty($overrides['migrate_plus.migration.su_stanford_person']['source']['authentication']['client_id']);
     $this->assertEmpty($overrides['migrate_plus.migration.su_stanford_person']['source']['authentication']['client_secret']);
-    $this->assertEmpty($overrides['migrate_plus.migration.su_stanford_person']['source']['urls']);
   }
 
   /**
@@ -156,38 +153,10 @@ public function testConfigOverrides() {
         }
       });
 
-    $this->configOverrides->loadOverrides(['migrate_plus.migration.su_stanford_person']);
-
-    drupal_static_reset('cap_source_urls');
-    $overrides = $this->configOverrides->loadOverrides(['migrate_plus.migration.su_stanford_person']);
-
-    $expected_urls = [
-      'http://localhost.orgs?ps=15&whitelist=fooBar,barFoo',
-      'http://localhost.workgroup?p=1&ps=15&whitelist=fooBar,barFoo',
-      'http://localhost.workgroup?p=2&ps=15&whitelist=fooBar,barFoo',
-      'http://localhost.sunet?whitelist=fooBar,barFoo',
-    ];
-    asort($expected_urls);
-    asort($overrides['migrate_plus.migration.su_stanford_person']['source']['urls']);
-    foreach ($overrides['migrate_plus.migration.su_stanford_person']['source']['urls'] as &$url) {
-      $url = urldecode($url);
-    }
-    $this->assertEquals(array_values($expected_urls), array_values($overrides['migrate_plus.migration.su_stanford_person']['source']['urls']));
-
-    $this->sunetUrlError = TRUE;
-    drupal_static_reset('cap_source_urls');
     $overrides = $this->configOverrides->loadOverrides(['migrate_plus.migration.su_stanford_person']);
-    $this->assertFalse($overrides['migrate_plus.migration.su_stanford_person']['status']);
-  }
 
-  /**
-   * Cap mock service callback.
-   */
-  public function getSunetUrlCallback() {
-    if ($this->sunetUrlError) {
-      throw new \Exception('Error getting sunet url');
-    }
-    return Url::fromUri('http://localhost.sunet');
+    $this->assertEquals('foo', $overrides['migrate_plus.migration.su_stanford_person']['source']['authentication']['client_id']);
+    $this->assertEquals('bar', $overrides['migrate_plus.migration.su_stanford_person']['source']['authentication']['client_secret']);
   }
 
 }
diff --git a/modules/stanford_person/modules/stanford_person_importer/tests/src/Unit/Plugin/migrate/source/CapUrlTest.php b/modules/stanford_person/modules/stanford_person_importer/tests/src/Unit/Plugin/migrate/source/CapUrlTest.php
new file mode 100644
index 00000000..45f2df50
--- /dev/null
+++ b/modules/stanford_person/modules/stanford_person_importer/tests/src/Unit/Plugin/migrate/source/CapUrlTest.php
@@ -0,0 +1,119 @@
+<?php
+
+namespace Drupal\Tests\stanford_person_importer\Unit\Plugin\migrate\source;
+
+use Drupal\config_pages\ConfigPagesLoaderServiceInterface;
+use Drupal\Core\DependencyInjection\ContainerBuilder;
+use Drupal\Core\Entity\ContentEntityInterface;
+use Drupal\Core\Entity\EntityStorageInterface;
+use Drupal\Core\Entity\EntityTypeManagerInterface;
+use Drupal\Core\Field\FieldItemListInterface;
+use Drupal\Core\PathProcessor\OutboundPathProcessorInterface;
+use Drupal\Core\Url;
+use Drupal\Core\Utility\UnroutedUrlAssembler;
+use Drupal\migrate\Plugin\MigrationInterface;
+use Drupal\stanford_person_importer\CapInterface;
+use Drupal\stanford_person_importer\Plugin\migrate\source\CapUrl;
+use Drupal\Tests\UnitTestCase;
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpFoundation\RequestStack;
+
+class CapUrlTest extends UnitTestCase {
+
+  protected $plugin;
+
+  protected $profileCount = 10;
+
+  public function testUrls() {
+    $config_pages = $this->createMock(ConfigPagesLoaderServiceInterface::class);
+
+    $config_pages->method('getValue')
+      ->will($this->returnCallback([$this, 'getConfigPageValue']));
+    $entity = $this->createMock(ContentEntityInterface::class);
+    $field_list = $this->createMock(FieldItemListInterface::class);
+    $field_list->method('getString')->willReturn('org:code');
+    $entity->method('get')->willReturn($field_list);
+    $entity_storage = $this->createMock(EntityStorageInterface::class);
+    $entity_storage->method('load')->willReturn($entity);
+    $entity_type_manager = $this->createMock(EntityTypeManagerInterface::class);
+    $entity_type_manager->method('getStorage')->willReturn($entity_storage);
+    $migration = $this->createMock(MigrationInterface::class);
+
+    $container = new ContainerBuilder();
+
+    $container->set('config_pages.loader', $config_pages);
+    $container->set('config.factory', $this->getConfigFactoryStub([
+      'migrate_plus.migration.su_stanford_person' => [
+        'source' => [
+          'fields' => [
+            ['selector' => 'foo'],
+            ['selector' => 'bar/bin/foo'],
+            ['selector' => 'baz'],
+          ],
+        ],
+      ],
+    ]));
+    $container->set('entity_type.manager', $entity_type_manager);
+    $container->set('unrouted_url_assembler', $this->getUrlAssembler());
+
+    $cap = $this->createMock(CapInterface::class);
+    $cap->method('getTotalProfileCount')
+      ->will($this->returnCallback([$this, 'getCapProfileCount']));
+    $cap->method('getOrganizationUrl')
+      ->willReturn(Url::fromUri('http://orgurl'));
+    $cap->method('getWorkgroupUrl')
+      ->willReturn(Url::fromUri('http://workgroupurl'));
+    $cap->method('getSunetUrl')
+      ->willReturn(Url::fromUri('http://suneturl'));
+
+    $container->set('stanford_person_importer.cap', $cap);
+    \Drupal::setContainer($container);
+
+    $plugin = TestCapUrl::create($container, [
+      'fields' => [],
+      'ids' => [],
+    ], 'cap_url', [], $migration);
+
+    $this->assertEquals([
+      'http://orgurl?ps=15&whitelist=foo%2Cbar%2Cbaz',
+      'http://workgroupurl?p=1&ps=15&whitelist=foo%2Cbar%2Cbaz',
+      'http://workgroupurl?p=2&ps=15&whitelist=foo%2Cbar%2Cbaz',
+      'http://suneturl?whitelist=foo%2Cbar%2Cbaz',
+    ], $plugin->getSourceUrls());
+  }
+
+  public function getConfigPageValue($bundle, $field, $delta, $key) {
+    switch ($field) {
+      case 'su_person_orgs':
+        return [1, 2, 3];
+      case 'su_person_child_orgs':
+        return FALSE;
+      case 'su_person_workgroup':
+        return ['bar:foo', 'bin:foo'];
+      case 'su_person_sunetid':
+        return ['foofoofoo'];
+    }
+  }
+
+  protected function getUrlAssembler() {
+    $request_stack = new RequestStack();
+    $request_stack->push(new Request());
+    $path_processor = $this->createMock(OutboundPathProcessorInterface::class);
+    return new UnroutedUrlAssembler($request_stack, $path_processor);
+  }
+
+  public function getCapProfileCount() {
+    $count =  $this->profileCount;
+    $this->profileCount += 10;
+    return $count;
+  }
+
+}
+
+class TestCapUrl extends CapUrl {
+
+  public function getSourceUrls() {
+    return $this->sourceUrls;
+  }
+
+}