diff --git a/composer.json b/composer.json
index 1043ef6c778592d7c4de0b14031089754622d39d..05bd19a389c9c2d3e552c9b4e240a263b655b1ce 100644
--- a/composer.json
+++ b/composer.json
@@ -15,6 +15,7 @@
     },
     "require-dev": {
         "friendsofphp/php-cs-fixer": "^3.0",
+        "mockery/mockery": "^1.4",
         "phpstan/phpstan": "^1.0.0",
         "phpstan/phpstan-phpunit": "^1.0.0",
         "symfony/browser-kit": "^5.2",
diff --git a/composer.lock b/composer.lock
index 5fffde6bfb9af6da6a4b184f346338b1c64ee7c8..b0908c422324f314c9d6d6d94016df8aebdf3e85 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
         "This file is @generated automatically"
     ],
-    "content-hash": "65a99e10023342cd5a76e629d1a0bb95",
+    "content-hash": "3a8d035bae1974a280bd26efab4b7c6d",
     "packages": [
         {
             "name": "adldap2/adldap2",
@@ -7726,6 +7726,129 @@
             ],
             "time": "2021-10-05T08:12:17+00:00"
         },
+        {
+            "name": "hamcrest/hamcrest-php",
+            "version": "v2.0.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/hamcrest/hamcrest-php.git",
+                "reference": "8c3d0a3f6af734494ad8f6fbbee0ba92422859f3"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/hamcrest/hamcrest-php/zipball/8c3d0a3f6af734494ad8f6fbbee0ba92422859f3",
+                "reference": "8c3d0a3f6af734494ad8f6fbbee0ba92422859f3",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^5.3|^7.0|^8.0"
+            },
+            "replace": {
+                "cordoval/hamcrest-php": "*",
+                "davedevelopment/hamcrest-php": "*",
+                "kodova/hamcrest-php": "*"
+            },
+            "require-dev": {
+                "phpunit/php-file-iterator": "^1.4 || ^2.0",
+                "phpunit/phpunit": "^4.8.36 || ^5.7 || ^6.5 || ^7.0"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "2.1-dev"
+                }
+            },
+            "autoload": {
+                "classmap": [
+                    "hamcrest"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "description": "This is the PHP port of Hamcrest Matchers",
+            "keywords": [
+                "test"
+            ],
+            "support": {
+                "issues": "https://github.com/hamcrest/hamcrest-php/issues",
+                "source": "https://github.com/hamcrest/hamcrest-php/tree/v2.0.1"
+            },
+            "time": "2020-07-09T08:09:16+00:00"
+        },
+        {
+            "name": "mockery/mockery",
+            "version": "1.4.4",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/mockery/mockery.git",
+                "reference": "e01123a0e847d52d186c5eb4b9bf58b0c6d00346"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/mockery/mockery/zipball/e01123a0e847d52d186c5eb4b9bf58b0c6d00346",
+                "reference": "e01123a0e847d52d186c5eb4b9bf58b0c6d00346",
+                "shasum": ""
+            },
+            "require": {
+                "hamcrest/hamcrest-php": "^2.0.1",
+                "lib-pcre": ">=7.0",
+                "php": "^7.3 || ^8.0"
+            },
+            "conflict": {
+                "phpunit/phpunit": "<8.0"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^8.5 || ^9.3"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.4.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-0": {
+                    "Mockery": "library/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Pádraic Brady",
+                    "email": "padraic.brady@gmail.com",
+                    "homepage": "http://blog.astrumfutura.com"
+                },
+                {
+                    "name": "Dave Marshall",
+                    "email": "dave.marshall@atstsolutions.co.uk",
+                    "homepage": "http://davedevelopment.co.uk"
+                }
+            ],
+            "description": "Mockery is a simple yet flexible PHP mock object framework",
+            "homepage": "https://github.com/mockery/mockery",
+            "keywords": [
+                "BDD",
+                "TDD",
+                "library",
+                "mock",
+                "mock objects",
+                "mockery",
+                "stub",
+                "test",
+                "test double",
+                "testing"
+            ],
+            "support": {
+                "issues": "https://github.com/mockery/mockery/issues",
+                "source": "https://github.com/mockery/mockery/tree/1.4.4"
+            },
+            "time": "2021-09-13T15:28:59+00:00"
+        },
         {
             "name": "monolog/monolog",
             "version": "2.3.5",
diff --git a/src/Resources/config/services_test.yaml b/src/Resources/config/services_test.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..9f7b377944dc200356818b5c56feb83847fd2a99
--- /dev/null
+++ b/src/Resources/config/services_test.yaml
@@ -0,0 +1,7 @@
+services:
+  Dbp\Relay\LdapPersonProviderBundle\TestUtils\DummyLDAPApiProvider:
+    autowire: true
+    autoconfigure: true
+
+  Dbp\Relay\BasePersonBundle\API\PersonProviderInterface:
+    '@Dbp\Relay\LdapPersonProviderBundle\TestUtils\DummyLDAPApiProvider'
diff --git a/src/TestUtils/DummyLDAPApiProvider.php b/src/TestUtils/DummyLDAPApiProvider.php
new file mode 100644
index 0000000000000000000000000000000000000000..c1dde5ba782857609171a96bf5ec60caa4cc93ce
--- /dev/null
+++ b/src/TestUtils/DummyLDAPApiProvider.php
@@ -0,0 +1,34 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Dbp\Relay\LdapPersonProviderBundle\TestUtils;
+
+use Dbp\Relay\BasePersonBundle\Entity\Person;
+use Dbp\Relay\LdapPersonProviderBundle\API\LDAPApiProviderInterface;
+use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
+
+class DummyLDAPApiProvider implements LDAPApiProviderInterface
+{
+    /**
+     * Allows manipulation of the person with a hash array of $attributes at the end of "personFromUserItem".
+     */
+    public function personFromUserItemPostHook(array $attributes, Person $person, bool $full = false)
+    {
+        // For example, you can parse the date of birth from the LDAP attribute and set it to the person object.
+
+//        $birthDate = $attributes['dateofbirth'][0];
+//        $person->setBirthDate($birthDate);
+    }
+
+    public function getPersonForExternalServiceHook(string $service, string $serviceID): Person
+    {
+        // For example, you can use the service and serviceID to get the person from some other service.
+
+//        if ($service === 'SOME-SERVICE') {
+//            return getPersonFromSomeService($serviceID);
+//        }
+
+        throw new BadRequestHttpException("Unknown service: $service");
+    }
+}
diff --git a/tests/Kernel.php b/tests/Kernel.php
index efb0a513247deb923a336aa42b5924fbc398a28a..ce54cd24ec468cc2ebdbd6541927f9a8d3a8e84d 100644
--- a/tests/Kernel.php
+++ b/tests/Kernel.php
@@ -4,9 +4,15 @@ declare(strict_types=1);
 
 namespace Dbp\Relay\LdapPersonProviderBundle\Tests;
 
+use ApiPlatform\Core\Bridge\Symfony\Bundle\ApiPlatformBundle;
+use Dbp\Relay\BasePersonBundle\DbpRelayBasePersonBundle;
+use Dbp\Relay\CoreBundle\DbpRelayCoreBundle;
 use Dbp\Relay\LdapPersonProviderBundle\DbpRelayLdapPersonProviderBundle;
+use Nelmio\CorsBundle\NelmioCorsBundle;
 use Symfony\Bundle\FrameworkBundle\FrameworkBundle;
 use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait;
+use Symfony\Bundle\SecurityBundle\SecurityBundle;
+use Symfony\Bundle\TwigBundle\TwigBundle;
 use Symfony\Component\Config\Loader\LoaderInterface;
 use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
 use Symfony\Component\HttpKernel\Kernel as BaseKernel;
@@ -18,19 +24,26 @@ class Kernel extends BaseKernel
     public function registerBundles(): iterable
     {
         yield new FrameworkBundle();
+        yield new ApiPlatformBundle();
+        yield new DbpRelayBasePersonBundle();
+        yield new DbpRelayCoreBundle();
         yield new DbpRelayLdapPersonProviderBundle();
+        yield new NelmioCorsBundle();
+        yield new SecurityBundle();
+        yield new TwigBundle();
     }
 
     protected function configureContainer(ContainerConfigurator $container, LoaderInterface $loader)
     {
         $container->import('@DbpRelayCoreBundle/Resources/config/services_test.yaml');
+        $container->import('@DbpRelayLdapPersonProviderBundle/Resources/config/services_test.yaml');
         $container->extension('framework', [
             'test' => true,
             'secret' => '',
         ]);
 
         $container->extension('dbp_relay_ldap_person_provider', [
-            'secret_token' => 'secret-test',
+            'ldap' => [],
         ]);
     }
 }
diff --git a/tests/PersonTest.php b/tests/PersonTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..991099f6739b65f37917b0daf07bac042c3965b2
--- /dev/null
+++ b/tests/PersonTest.php
@@ -0,0 +1,86 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Tugraz\Relay\TugrazBundle\Tests;
+
+use Adldap\Connections\ConnectionInterface;
+use Adldap\Models\User as AdldapUser;
+use Adldap\Query\Builder;
+use Adldap\Query\Grammar;
+use ApiPlatform\Core\Bridge\Symfony\Bundle\Test\ApiTestCase;
+use Dbp\Relay\LdapPersonProviderBundle\Service\LDAPApi;
+use Dbp\Relay\LdapPersonProviderBundle\Service\LDAPPersonProvider;
+use Dbp\Relay\LdapPersonProviderBundle\TestUtils\DummyLDAPApiProvider;
+use Mockery;
+
+class PersonTest extends ApiTestCase
+{
+    /**
+     * @var LDAPApi
+     */
+    private $api;
+
+    /**
+     * @var LDAPPersonProvider
+     */
+    private $provider;
+
+    protected function setUp(): void
+    {
+        parent::setUp();
+        $ldapApiProvider = new DummyLDAPApiProvider();
+        $this->api = new LDAPApi(self::createClient()->getContainer(), $ldapApiProvider);
+        $this->api->setConfig([
+            'ldap' => [
+                'attributes' => [
+                    'email' => 'email',
+                    'birthday' => 'dateofbirth',
+                ]
+            ]
+        ]);
+
+        $this->provider = new LDAPPersonProvider($this->api);
+    }
+
+    public function testBasic()
+    {
+        $this->expectExceptionMessageMatches('/.*/');
+        $this->provider->getPerson('____nope____');
+    }
+
+    protected function newBuilder()
+    {
+        $connection = Mockery::mock(ConnectionInterface::class);
+
+        return new Builder($connection, new Grammar());
+    }
+
+    public function testLDAPParsing()
+    {
+        $user = new AdldapUser([
+            'cn' => ['foobar'],
+            'givenName' => ['John'],
+            'sn' => ['Doe'],
+        ], $this->newBuilder());
+
+        $person = $this->api->personFromUserItem($user, false);
+        $this->assertEquals('John', $person->getGivenName());
+        $this->assertEquals('Doe', $person->getFamilyName());
+    }
+
+    public function testBirthDateParsing()
+    {
+        $variants = ['1994-06-24', '1994-06-24 00:00:00'];
+        foreach ($variants as $variant) {
+            $user = new AdldapUser([
+                'cn' => ['foobar'],
+                'dateofbirth' => [$variant],
+            ], $this->newBuilder());
+
+            $person = $this->api->personFromUserItem($user, false);
+            $this->assertNotNull($person->getBirthDate());
+            $this->assertEquals('1994-06-24', $person->getBirthDate());
+        }
+    }
+}