diff --git a/app/code/Magento/Webapi/Model/Config.php b/app/code/Magento/Webapi/Model/Config.php
index 45d29bc59cf0d6a1c9c1be78ff84343f50b1029d..53bfda46eb495629ade3733cc1b7f5783aca4b7d 100644
--- a/app/code/Magento/Webapi/Model/Config.php
+++ b/app/code/Magento/Webapi/Model/Config.php
@@ -8,6 +8,8 @@ namespace Magento\Webapi\Model;
 
 use Magento\Webapi\Model\Cache\Type\Webapi as WebapiCache;
 use Magento\Webapi\Model\Config\Reader;
+use Magento\Framework\App\ObjectManager;
+use Magento\Framework\Serialize\SerializerInterface;
 
 /**
  * Web API Config Model.
@@ -40,16 +42,25 @@ class Config
      */
     protected $services;
 
+    /**
+     * @var SerializerInterface
+     */
+    private $serializer;
+
     /**
      * Initialize dependencies.
      *
      * @param WebapiCache $cache
      * @param Reader $configReader
      */
-    public function __construct(WebapiCache $cache, Reader $configReader)
-    {
+    public function __construct(
+        WebapiCache $cache,
+        Reader $configReader,
+        SerializerInterface $serializer = null
+    ) {
         $this->cache = $cache;
         $this->configReader = $configReader;
+        $this->serializer = $serializer ?: ObjectManager::getInstance()->get(SerializerInterface::class);
     }
 
     /**
@@ -62,10 +73,10 @@ class Config
         if (null === $this->services) {
             $services = $this->cache->load(self::CACHE_ID);
             if ($services && is_string($services)) {
-                $this->services = unserialize($services);
+                $this->services = $this->serializer->unserialize($services);
             } else {
                 $this->services = $this->configReader->read();
-                $this->cache->save(serialize($this->services), self::CACHE_ID);
+                $this->cache->save($this->serializer->serialize($this->services), self::CACHE_ID);
             }
         }
         return $this->services;
diff --git a/app/code/Magento/Webapi/Model/ServiceMetadata.php b/app/code/Magento/Webapi/Model/ServiceMetadata.php
index b75d10f9a271f7a3f39fff2ac9494f020b5cf660..1b1eea3442a00a8634acbadf932063f1d6464164 100644
--- a/app/code/Magento/Webapi/Model/ServiceMetadata.php
+++ b/app/code/Magento/Webapi/Model/ServiceMetadata.php
@@ -7,6 +7,8 @@ namespace Magento\Webapi\Model;
 
 use Magento\Webapi\Model\Config\Converter;
 use Magento\Webapi\Model\Cache\Type\Webapi as WebApiCache;
+use Magento\Framework\App\ObjectManager;
+use Magento\Framework\Serialize\SerializerInterface;
 
 /**
  * Service Metadata Model
@@ -74,6 +76,11 @@ class ServiceMetadata
      */
     protected $typeProcessor;
 
+    /**
+     * @var SerializerInterface
+     */
+    private $serializer;
+
     /**
      * Initialize dependencies.
      *
@@ -86,12 +93,14 @@ class ServiceMetadata
         \Magento\Webapi\Model\Config $config,
         WebApiCache $cache,
         \Magento\Webapi\Model\Config\ClassReflector $classReflector,
-        \Magento\Framework\Reflection\TypeProcessor $typeProcessor
+        \Magento\Framework\Reflection\TypeProcessor $typeProcessor,
+        SerializerInterface $serializer = null
     ) {
         $this->config = $config;
         $this->cache = $cache;
         $this->classReflector = $classReflector;
         $this->typeProcessor = $typeProcessor;
+        $this->serializer = $serializer ?: ObjectManager::getInstance()->get(SerializerInterface::class);
     }
 
     /**
@@ -142,12 +151,18 @@ class ServiceMetadata
             $servicesConfig = $this->cache->load(self::SERVICES_CONFIG_CACHE_ID);
             $typesData = $this->cache->load(self::REFLECTED_TYPES_CACHE_ID);
             if ($servicesConfig && is_string($servicesConfig) && $typesData && is_string($typesData)) {
-                $this->services = unserialize($servicesConfig);
-                $this->typeProcessor->setTypesData(unserialize($typesData));
+                $this->services = $this->serializer->unserialize($servicesConfig);
+                $this->typeProcessor->setTypesData($this->serializer->unserialize($typesData));
             } else {
                 $this->services = $this->initServicesMetadata();
-                $this->cache->save(serialize($this->services), self::SERVICES_CONFIG_CACHE_ID);
-                $this->cache->save(serialize($this->typeProcessor->getTypesData()), self::REFLECTED_TYPES_CACHE_ID);
+                $this->cache->save(
+                    $this->serializer->serialize($this->services),
+                    self::SERVICES_CONFIG_CACHE_ID
+                );
+                $this->cache->save(
+                    $this->serializer->serialize($this->typeProcessor->getTypesData()),
+                    self::REFLECTED_TYPES_CACHE_ID
+                );
             }
         }
         return $this->services;
@@ -256,12 +271,18 @@ class ServiceMetadata
             $routesConfig = $this->cache->load(self::ROUTES_CONFIG_CACHE_ID);
             $typesData = $this->cache->load(self::REFLECTED_TYPES_CACHE_ID);
             if ($routesConfig && is_string($routesConfig) && $typesData && is_string($typesData)) {
-                $this->routes = unserialize($routesConfig);
-                $this->typeProcessor->setTypesData(unserialize($typesData));
+                $this->routes = $this->serializer->unserialize($routesConfig);
+                $this->typeProcessor->setTypesData($this->serializer->unserialize($typesData));
             } else {
                 $this->routes = $this->initRoutesMetadata();
-                $this->cache->save(serialize($this->routes), self::ROUTES_CONFIG_CACHE_ID);
-                $this->cache->save(serialize($this->typeProcessor->getTypesData()), self::REFLECTED_TYPES_CACHE_ID);
+                $this->cache->save(
+                    $this->serializer->serialize($this->routes),
+                    self::ROUTES_CONFIG_CACHE_ID
+                );
+                $this->cache->save(
+                    $this->serializer->serialize($this->typeProcessor->getTypesData()),
+                    self::REFLECTED_TYPES_CACHE_ID
+                );
             }
         }
         return $this->routes;
diff --git a/app/code/Magento/Webapi/Test/Unit/Model/ConfigTest.php b/app/code/Magento/Webapi/Test/Unit/Model/ConfigTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..74280f61916d7182e90bdf1e9b6125da55a6c31b
--- /dev/null
+++ b/app/code/Magento/Webapi/Test/Unit/Model/ConfigTest.php
@@ -0,0 +1,96 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Webapi\Test\Unit\Model;
+
+use Magento\Framework\Serialize\SerializerInterface;
+use Magento\Webapi\Model\Config;
+use Magento\Webapi\Model\Config\Reader;
+use Magento\Webapi\Model\Cache\Type\Webapi;
+
+class ConfigTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var Config
+     */
+    private $config;
+
+    /**
+     * @var Webapi|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $webapiCacheMock;
+
+    /**
+     * @var Reader|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $configReaderMock;
+
+    /**
+     * @var SerializerInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $serializerMock;
+
+    protected function setUp()
+    {
+        $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
+
+        $this->webapiCacheMock = $this->getMock(\Magento\Webapi\Model\Cache\Type\Webapi::class, [], [], '', false);
+        $this->configReaderMock = $this->getMock(\Magento\Webapi\Model\Config\Reader::class, [], [], '', false);
+        $this->serializerMock = $this->getMock(SerializerInterface::class);
+
+        $this->config = $objectManager->getObject(
+            Config::class,
+            [
+                'cache' => $this->webapiCacheMock,
+                'configReader' => $this->configReaderMock,
+                'serializer' => $this->serializerMock
+            ]
+        );
+    }
+
+    public function testGetServices()
+    {
+        $data = ['foo' => 'bar'];
+        $serializedData = 'serialized data';
+        $this->webapiCacheMock->expects($this->once())
+            ->method('load')
+            ->with(Config::CACHE_ID)
+            ->willReturn($serializedData);
+        $this->serializerMock->expects($this->once())
+            ->method('unserialize')
+            ->with($serializedData)
+            ->willReturn($data);
+        $this->config->getServices();
+        $this->assertEquals($data, $this->config->getServices());
+    }
+
+    public function testGetServicesNoCache()
+    {
+        $data = ['foo' => 'bar'];
+        $serializedData = 'serialized data';
+        $this->webapiCacheMock->expects($this->once())
+            ->method('load')
+            ->with(Config::CACHE_ID)
+            ->willReturn(false);
+        $this->serializerMock->expects($this->never())
+            ->method('unserialize');
+        $this->configReaderMock->expects($this->once())
+            ->method('read')
+            ->willReturn($data);
+        $this->serializerMock->expects($this->once())
+            ->method('serialize')
+            ->with($data)
+            ->willReturn($serializedData);
+        $this->webapiCacheMock->expects($this->once())
+            ->method('save')
+            ->with(
+                $serializedData,
+                Config::CACHE_ID
+            );
+
+        $this->config->getServices();
+        $this->assertEquals($data, $this->config->getServices());
+    }
+}
diff --git a/app/code/Magento/Webapi/Test/Unit/Model/ServiceMetadataTest.php b/app/code/Magento/Webapi/Test/Unit/Model/ServiceMetadataTest.php
index 29c1bf90402ebe36d6ca91c5585cacb03f739cc3..7aa99a69c109a145c57f9e81c3d571a03663a381 100644
--- a/app/code/Magento/Webapi/Test/Unit/Model/ServiceMetadataTest.php
+++ b/app/code/Magento/Webapi/Test/Unit/Model/ServiceMetadataTest.php
@@ -1,187 +1,444 @@
 <?php
 /**
- * ServiceMetadata Unit tests.
- *
  * Copyright © 2016 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
-
-/**
- * Class implements tests for \Magento\Webapi\Model\ServiceMetadata class.
- */
 namespace Magento\Webapi\Test\Unit\Model;
 
+use Magento\Framework\Serialize\SerializerInterface;
+use Magento\Webapi\Model\Config;
+use Magento\Webapi\Model\Cache\Type\Webapi;
+use Magento\Webapi\Model\Config\ClassReflector;
+use Magento\Framework\Reflection\TypeProcessor;
+use Magento\Webapi\Model\ServiceMetadata;
+use Magento\Customer\Api\CustomerRepositoryInterface;
+
 class ServiceMetadataTest extends \PHPUnit_Framework_TestCase
 {
-    /** @var \Magento\Webapi\Model\ServiceMetadata */
-    protected $serviceMetadata;
+    /**
+     * @var ServiceMetadata
+     */
+    private $serviceMetadata;
+
+    /**
+     * @var Webapi|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $cacheMock;
+
+    /**
+     * @var Config|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $configMock;
 
     /**
-     * Set up helper.
-     * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
+     * @var ClassReflector|\PHPUnit_Framework_MockObject_MockObject
      */
+    private $classReflectorMock;
+
+    /**
+     * @var TypeProcessor|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $typeProcessorMock;
+
+    /**
+     * @var SerializerInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $serializerMock;
+
     protected function setUp()
     {
-        $interfaceParameters = [
-            'activateById' => [
+        $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
+
+        $this->configMock = $this->getMock(Config::class, [], [], '', false);
+        $this->cacheMock = $this->getMock(Webapi::class, [], [], '', false);
+        $this->classReflectorMock = $this->getMock(ClassReflector::class, [], [], '', false);
+        $this->typeProcessorMock = $this->getMock(TypeProcessor::class, [], [], '', false);
+        $this->serializerMock = $this->getMock(SerializerInterface::class);
+
+        $this->serviceMetadata = $objectManager->getObject(
+            ServiceMetadata::class,
+            [
+                'config' => $this->configMock,
+                'cache' => $this->cacheMock,
+                'classReflector' => $this->classReflectorMock,
+                'typeProcessor' => $this->typeProcessorMock,
+                'serializer' => $this->serializerMock
+            ]
+        );
+    }
+
+    public function testGetServicesConfig()
+    {
+        $servicesConfig = ['foo' => 'bar'];
+        $typeData = ['bar' => 'foo'];
+        $serializedServicesConfig = 'serialized services config';
+        $serializedTypeData = 'serialized type data';
+        $this->cacheMock->expects($this->at(0))
+            ->method('load')
+            ->with(ServiceMetadata::SERVICES_CONFIG_CACHE_ID)
+            ->willReturn($serializedServicesConfig);
+        $this->cacheMock->expects($this->at(1))
+            ->method('load')
+            ->with(ServiceMetadata::REFLECTED_TYPES_CACHE_ID)
+            ->willReturn($serializedTypeData);
+        $this->serializerMock->expects($this->at(0))
+            ->method('unserialize')
+            ->with($serializedServicesConfig)
+            ->willReturn($servicesConfig);
+        $this->serializerMock->expects($this->at(1))
+            ->method('unserialize')
+            ->with($serializedTypeData)
+            ->willReturn($typeData);
+        $this->typeProcessorMock->expects($this->once())
+            ->method('setTypesData')
+            ->with($typeData);
+        $this->serviceMetadata->getServicesConfig();
+        $this->assertEquals($servicesConfig, $this->serviceMetadata->getServicesConfig());
+    }
+
+    public function testGetServicesConfigNoCache()
+    {
+        $servicesConfig = [
+            'services' => [
+                CustomerRepositoryInterface::class => [
+                    'V1' => [
+                        'methods' => [
+                            'getById' => [
+                                'resources' => [
+                                    [
+                                        'Magento_Customer::customer',
+                                    ]
+                                ],
+                                'secure' => false
+                            ]
+                        ]
+                    ]
+                ]
+            ]
+        ];
+        $methodsReflectionData = [
+            'getById' => [
+                'documentation' => 'Get customer by customer ID.',
                 'interface' => [
                     'in' => [
                         'parameters' => [
                             'customerId' => [
-                                'force' => true,
-                                'value' => '%customer_id%',
-                            ],
-                            'requiredInputParameter' => [
+                                'type' => 'int',
                                 'required' => true,
-                            ],
-                        ],
+                                'documentation' => null
+                            ]
+                        ]
                     ],
                     'out' => [
                         'parameters' => [
-                            'outputParameter' => [
-                                'type' => 'string',
+                            'result' => [
+                                'type' => 'CustomerDataCustomerInterface',
+                                'required' => true,
+                                'documentation' => null
+                            ]
+                        ]
+                    ]
+                ]
+            ]
+        ];
+        $servicesMetadata = [
+            'customerCustomerRepositoryV1' => [
+                'methods' => array_merge_recursive(
+                    [
+                        'getById' => [
+                            'resources' => [
+                                [
+                                    'Magento_Customer::customer',
+                                ],
                             ],
-                        ],
+                            'method' => 'getById',
+                            'inputRequired' => false,
+                            'isSecure' => false,
+                        ]
                     ],
-                ],
-            ],
+                    $methodsReflectionData
+                ),
+                'class' => CustomerRepositoryInterface::class,
+                'description' => 'Customer CRUD interface.'
+            ]
         ];
-        $classReflection = $this->getMock(
-            \Magento\Webapi\Model\Config\ClassReflector::class,
-            ['reflectClassMethods', 'extractClassDescription'],
-            [],
-            '',
-            false
-        );
-        $classReflection->expects($this->any())
+        $typeData = [
+            'CustomerDataCustomerInterface' => [
+                'documentation' => 'Customer interface.',
+                'parameters' => [
+                    'id' => [
+                        'type' => 'int',
+                        'required' => false,
+                        'documentation' => 'Customer id'
+                    ]
+                ]
+            ]
+        ];
+        $serializedServicesConfig = 'serialized services config';
+        $serializedTypeData = 'serialized type data';
+        $this->cacheMock->expects($this->at(0))
+            ->method('load')
+            ->with(ServiceMetadata::SERVICES_CONFIG_CACHE_ID)
+            ->willReturn(false);
+        $this->cacheMock->expects($this->at(1))
+            ->method('load')
+            ->with(ServiceMetadata::REFLECTED_TYPES_CACHE_ID)
+            ->willReturn(false);
+        $this->serializerMock->expects($this->never())
+            ->method('unserialize');
+        $this->configMock->expects($this->once())
+            ->method('getServices')
+            ->willReturn($servicesConfig);
+        $this->classReflectorMock->expects($this->once())
             ->method('reflectClassMethods')
-            ->will($this->returnValue($interfaceParameters));
-        $classReflection->expects($this->any())
+            ->willReturn($methodsReflectionData);
+        $this->classReflectorMock->expects($this->once())
             ->method('extractClassDescription')
-            ->will($this->returnValue('classDescription'));
+            ->with(CustomerRepositoryInterface::class)
+            ->willReturn('Customer CRUD interface.');
+        $this->typeProcessorMock->expects($this->once())
+            ->method('getTypesData')
+            ->willReturn($typeData);
+        $this->serializerMock->expects($this->at(0))
+            ->method('serialize')
+            ->with($servicesMetadata)
+            ->willReturn($serializedServicesConfig);
+        $this->serializerMock->expects($this->at(1))
+            ->method('serialize')
+            ->with($typeData)
+            ->willReturn($serializedTypeData);
+        $this->cacheMock->expects($this->at(2))
+            ->method('save')
+            ->with(
+                $serializedServicesConfig,
+                ServiceMetadata::SERVICES_CONFIG_CACHE_ID
+            );
+        $this->cacheMock->expects($this->at(3))
+            ->method('save')
+            ->with(
+                $serializedTypeData,
+                ServiceMetadata::REFLECTED_TYPES_CACHE_ID
+            );
+        $this->serviceMetadata->getServicesConfig();
+        $this->assertEquals($servicesMetadata, $this->serviceMetadata->getServicesConfig());
+    }
+
+    public function testGetRoutesConfig()
+    {
+        $routesConfig = ['foo' => 'bar'];
+        $typeData = ['bar' => 'foo'];
+        $serializedRoutesConfig = 'serialized routes config';
+        $serializedTypeData = 'serialized type data';
+        $this->cacheMock->expects($this->at(0))
+            ->method('load')
+            ->with(ServiceMetadata::ROUTES_CONFIG_CACHE_ID)
+            ->willReturn($serializedRoutesConfig);
+        $this->cacheMock->expects($this->at(1))
+            ->method('load')
+            ->with(ServiceMetadata::REFLECTED_TYPES_CACHE_ID)
+            ->willReturn($serializedTypeData);
+        $this->serializerMock->expects($this->at(0))
+            ->method('unserialize')
+            ->with($serializedRoutesConfig)
+            ->willReturn($routesConfig);
+        $this->serializerMock->expects($this->at(1))
+            ->method('unserialize')
+            ->with($serializedTypeData)
+            ->willReturn($typeData);
+        $this->typeProcessorMock->expects($this->once())
+            ->method('setTypesData')
+            ->with($typeData);
+        $this->serviceMetadata->getRoutesConfig();
+        $this->assertEquals($routesConfig, $this->serviceMetadata->getRoutesConfig());
+    }
 
+    public function testGetRoutesConfigNoCache()
+    {
         $servicesConfig = [
-            'services' => [\Magento\Customer\Api\AccountManagementInterface::class => [
-                    'V1' => [
-                        'methods' => [
-                            'activateById' => [
-                                'resources' => [
-                                    [
-                                        'Magento_Customer::manage',
-                                    ],
-                                ],
-                                'secure' => false,
-                            ],
-                        ],
-                    ],
-                ], \Magento\Customer\Api\CustomerRepositoryInterface::class => [
+            'services' => [
+                CustomerRepositoryInterface::class => [
                     'V1' => [
                         'methods' => [
                             'getById' => [
                                 'resources' => [
                                     [
                                         'Magento_Customer::customer',
-                                    ],
+                                    ]
                                 ],
-                                'secure' => false,
-                            ],
-                        ],
-                    ],
-                ],
+                                'secure' => false
+                            ]
+                        ]
+                    ]
+                ]
             ],
             'routes' => [
-                '/V1/customers/me/activate' => [
-                    'PUT' => [
+                '/V1/customers/:customerId' => [
+                    'GET' => [
                         'secure' => false,
                         'service' => [
-                            'class' => \Magento\Customer\Api\AccountManagementInterface::class,
-                            'method' => 'activateById',
+                            'class' => CustomerRepositoryInterface::class,
+                            'method' => 'getById'
                         ],
                         'resources' => [
-                            'self' => true,
+                            'Magento_Customer::customer' => true
                         ],
+                        'parameters' => []
+                    ]
+                ]
+            ],
+            'class' => CustomerRepositoryInterface::class,
+            'description' => 'Customer CRUD interface.',
+        ];
+        $methodsReflectionData = [
+            'getById' => [
+                'documentation' => 'Get customer by customer ID.',
+                'interface' => [
+                    'in' => [
                         'parameters' => [
                             'customerId' => [
-                                'force' => true,
-                                'value' => '%customer_id%',
-                            ],
-                        ],
+                                'type' => 'int',
+                                'required' => true,
+                                'documentation' => null
+                            ]
+                        ]
                     ],
-                ],
-                '/V1/customers/:customerId' => [
-                    'GET' => [
-                        'secure' => false,
-                        'service' => [
-                            'class' => \Magento\Customer\Api\CustomerRepositoryInterface::class,
-                            'method' => 'getById',
-                        ],
-                        'resources' => [
-                            'Magento_Customer::customer' => true,
-                        ],
+                    'out' => [
                         'parameters' => [
-                        ],
+                            'result' => [
+                                'type' => 'CustomerDataCustomerInterface',
+                                'required' => true,
+                                'documentation' => null
+                            ]
+                        ]
+                    ]
+                ]
+            ]
+        ];
+        $routesMetadata = [
+            'customerCustomerRepositoryV1' => [
+                'methods' => array_merge_recursive(
+                    [
+                        'getById' => [
+                            'resources' => [
+                                [
+                                    'Magento_Customer::customer',
+                                ]
+                            ],
+                            'method' => 'getById',
+                            'inputRequired' => false,
+                            'isSecure' => false,
+                        ]
                     ],
+                    $methodsReflectionData
+                ),
+                'routes' => [
+                    '/V1/customers/:customerId' => [
+                        'GET' => [
+                            'method' => 'getById',
+                            'parameters' => []
+                        ]
+                    ]
                 ],
+                'class' => CustomerRepositoryInterface::class,
+                'description' => 'Customer CRUD interface.'
             ]
         ];
-
-        /**
-         * @var $cacheMock \Magento\Webapi\Model\Cache\Type\Webapi
-         */
-        $cacheMock = $this->getMockBuilder(\Magento\Webapi\Model\Cache\Type\Webapi::class)
-            ->disableOriginalConstructor()
-            ->getMock();
-
-        /** @var $readerMock \Magento\Webapi\Model\Config\Reader */
-        $readerMock = $this->getMockBuilder(\Magento\Webapi\Model\Config\Reader::class)
-            ->disableOriginalConstructor()
-            ->getMock();
-        $readerMock->expects($this->any())->method('read')->will($this->returnValue($servicesConfig));
-
-        /** @var $config \Magento\Webapi\Model\Config */
-        $config = new \Magento\Webapi\Model\Config($cacheMock, $readerMock);
-
-        $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
-        $typeProcessor = $objectManager->getObject(\Magento\Framework\Reflection\TypeProcessor::class);
-
-        /** @var $config \Magento\Webapi\Model\ServiceMetadata */
-        $this->serviceMetadata = new \Magento\Webapi\Model\ServiceMetadata(
-            $config,
-            $cacheMock,
-            $classReflection,
-            $typeProcessor
-        );
-
-        parent::setUp();
+        $typeData = [
+            'CustomerDataCustomerInterface' => [
+                'documentation' => 'Customer interface.',
+                'parameters' => [
+                    'id' => [
+                        'type' => 'int',
+                        'required' => false,
+                        'documentation' => 'Customer id'
+                    ]
+                ]
+            ]
+        ];
+        $serializedRoutesConfig = 'serialized routes config';
+        $serializedTypeData = 'serialized type data';
+        $this->cacheMock->expects($this->at(0))
+            ->method('load')
+            ->with(ServiceMetadata::ROUTES_CONFIG_CACHE_ID)
+            ->willReturn(false);
+        $this->cacheMock->expects($this->at(1))
+            ->method('load')
+            ->with(ServiceMetadata::REFLECTED_TYPES_CACHE_ID)
+            ->willReturn(false);
+        $this->serializerMock->expects($this->never())
+            ->method('unserialize');
+        $this->configMock->expects($this->exactly(2))
+            ->method('getServices')
+            ->willReturn($servicesConfig);
+        $this->classReflectorMock->expects($this->once())
+            ->method('reflectClassMethods')
+            ->willReturn($methodsReflectionData);
+        $this->classReflectorMock->expects($this->once())
+            ->method('extractClassDescription')
+            ->with(CustomerRepositoryInterface::class)
+            ->willReturn('Customer CRUD interface.');
+        $this->typeProcessorMock->expects($this->exactly(2))
+            ->method('getTypesData')
+            ->willReturn($typeData);
+        $this->serializerMock->expects($this->at(2))
+            ->method('serialize')
+            ->with($routesMetadata)
+            ->willReturn($serializedRoutesConfig);
+        $this->serializerMock->expects($this->at(3))
+            ->method('serialize')
+            ->with($typeData)
+            ->willReturn($serializedTypeData);
+        $this->cacheMock->expects($this->at(6))
+            ->method('save')
+            ->with(
+                $serializedRoutesConfig,
+                ServiceMetadata::ROUTES_CONFIG_CACHE_ID
+            );
+        $this->cacheMock->expects($this->at(7))
+            ->method('save')
+            ->with(
+                $serializedTypeData,
+                ServiceMetadata::REFLECTED_TYPES_CACHE_ID
+            );
+        $this->serviceMetadata->getRoutesConfig();
+        $this->assertEquals($routesMetadata, $this->serviceMetadata->getRoutesConfig());
     }
 
     /**
-     * Test identifying service name including subservices using class name.
-     *
-     * @dataProvider serviceNameDataProvider
+     * @dataProvider getServiceNameDataProvider
      */
     public function testGetServiceName($className, $version, $preserveVersion, $expected)
     {
-        $actual = $this->serviceMetadata->getServiceName($className, $version, $preserveVersion);
-        $this->assertEquals($expected, $actual);
+        $this->assertEquals(
+            $expected,
+            $this->serviceMetadata->getServiceName($className, $version, $preserveVersion)
+        );
     }
 
     /**
-     * Dataprovider for testGetServiceName
-     *
      * @return string
      */
-    public function serviceNameDataProvider()
+    public function getServiceNameDataProvider()
     {
         return [
-            [\Magento\Customer\Api\AccountManagementInterface::class, 'V1', false, 'customerAccountManagement'],
-            [\Magento\Customer\Api\AddressRepositoryInterface::class, 'V1', true, 'customerAddressRepositoryV1'],
+            [
+                \Magento\Customer\Api\AccountManagementInterface::class,
+                'V1',
+                false,
+                'customerAccountManagement'
+            ],
+            [
+                \Magento\Customer\Api\AddressRepositoryInterface::class,
+                'V1',
+                true,
+                'customerAddressRepositoryV1'
+            ],
         ];
     }
 
     /**
      * @expectedException \InvalidArgumentException
-     * @dataProvider dataProviderForTestGetServiceNameInvalidName
+     * @dataProvider getServiceNameInvalidNameDataProvider
      */
     public function testGetServiceNameInvalidName($interfaceClassName, $version)
     {
@@ -189,111 +446,19 @@ class ServiceMetadataTest extends \PHPUnit_Framework_TestCase
     }
 
     /**
-     * Dataprovider for testGetServiceNameInvalidName
-     *
      * @return string
      */
-    public function dataProviderForTestGetServiceNameInvalidName()
+    public function getServiceNameInvalidNameDataProvider()
     {
         return [
-            ['BarV1Interface', 'V1'], // Missed vendor, module, 'Service'
+            ['BarV1Interface', 'V1'], // Missed vendor, module and Service
             ['Service\\V1Interface', 'V1'], // Missed vendor and module
             ['Magento\\Foo\\Service\\BarVxInterface', 'V1'], // Version number should be a number
-            ['Magento\\Foo\\Service\\BarInterface', 'V1'], // Version missed
-            ['Magento\\Foo\\Service\\BarV1', 'V1'], // 'Interface' missed
-            ['Foo\\Service\\BarV1Interface', 'V1'], // Module missed
-            ['Foo\\BarV1Interface', 'V1'] // Module and 'Service' missed
-        ];
-    }
-
-    public function testGetServiceMetadata()
-    {
-        $expectedResult = [
-            'methods' => [
-                'activateById' => [
-                    'method' => 'activateById',
-                    'inputRequired' => '',
-                    'isSecure' => '',
-                    'resources' => [['Magento_Customer::manage']],
-                    'interface' => [
-                        'in' => [
-                            'parameters' => [
-                                'customerId' => [
-                                    'force' => true,
-                                    'value' => '%customer_id%',
-                                ],
-                                'requiredInputParameter' => [
-                                    'required' => true,
-                                ],
-                            ],
-                        ],
-                        'out' => [
-                            'parameters' => [
-                                'outputParameter' => [
-                                    'type' => 'string',
-                                ],
-                            ],
-                        ],
-                    ],
-                ],
-            ],
-            'class' => \Magento\Customer\Api\AccountManagementInterface::class,
-            'description' => 'classDescription',
+            ['Magento\\Foo\\Service\\BarInterface', 'V1'], // Missed version
+            ['Magento\\Foo\\Service\\BarV1', 'V1'], // Missed Interface
+            ['Foo\\Service\\BarV1Interface', 'V1'], // Missed module
+            ['Foo\\BarV1Interface', 'V1'] // Missed module and Service
         ];
-        $result = $this->serviceMetadata->getServiceMetadata('customerAccountManagementV1');
-        $this->assertEquals($expectedResult, $result);
     }
 
-    public function testGetRouteMetadata()
-    {
-        $expectedResult = [
-            'methods' => [
-                'activateById' => [
-                    'method' => 'activateById',
-                    'inputRequired' => '',
-                    'isSecure' => '',
-                    'resources' => [['Magento_Customer::manage']],
-                    'interface' => [
-                        'in' => [
-                            'parameters' => [
-                                'customerId' => [
-                                    'force' => true,
-                                    'value' => '%customer_id%',
-                                ],
-                                'requiredInputParameter' => [
-                                    'required' => true,
-                                ],
-                            ],
-                        ],
-                        'out' => [
-                            'parameters' => [
-                                'outputParameter' => [
-                                    'type' => 'string',
-                                ],
-                            ],
-                        ],
-                    ],
-                ],
-            ],
-            'class' => \Magento\Customer\Api\AccountManagementInterface::class,
-            'description' => 'classDescription',
-            'routes' => [
-                '/V1/customers/me/activate' => [
-                    'PUT' => [
-                        'method' => 'activateById',
-                        'parameters' => [
-                            'customerId' => [
-                                'force' => true,
-                                'value' => '%customer_id%'
-                            ]
-                        ]
-                    ]
-                ]
-            ]
-        ];
-        $result = $this->serviceMetadata->getRouteMetadata('customerAccountManagementV1');
-        $this->assertEquals($expectedResult, $result);
-    }
 }
-
-require_once realpath(__DIR__ . '/../_files/test_interfaces.php');
diff --git a/dev/tests/integration/testsuite/Magento/Webapi/Model/ServiceMetadataTest.php b/dev/tests/integration/testsuite/Magento/Webapi/Model/ServiceMetadataTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..c74b0888d24d548bf2b673bd211aa4f31f0316dd
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Webapi/Model/ServiceMetadataTest.php
@@ -0,0 +1,250 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Webapi\Model;
+
+class ServiceMetadataTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Webapi\Model\ServiceMetadata
+     */
+    private $serviceMetadata;
+
+    /**
+     * Set up helper.
+     * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
+     */
+    protected function setUp()
+    {
+        $interfaceParameters = [
+            'activateById' => [
+                'interface' => [
+                    'in' => [
+                        'parameters' => [
+                            'customerId' => [
+                                'force' => true,
+                                'value' => '%customer_id%',
+                            ],
+                            'requiredInputParameter' => [
+                                'required' => true,
+                            ],
+                        ],
+                    ],
+                    'out' => [
+                        'parameters' => [
+                            'outputParameter' => [
+                                'type' => 'string',
+                            ],
+                        ],
+                    ],
+                ],
+            ],
+        ];
+        $classReflection = $this->getMock(
+            \Magento\Webapi\Model\Config\ClassReflector::class,
+            ['reflectClassMethods', 'extractClassDescription'],
+            [],
+            '',
+            false
+        );
+        $classReflection->expects($this->any())
+            ->method('reflectClassMethods')
+            ->will($this->returnValue($interfaceParameters));
+        $classReflection->expects($this->any())
+            ->method('extractClassDescription')
+            ->will($this->returnValue('classDescription'));
+
+        $servicesConfig = [
+            'services' => [\Magento\Customer\Api\AccountManagementInterface::class => [
+                    'V1' => [
+                        'methods' => [
+                            'activateById' => [
+                                'resources' => [
+                                    [
+                                        'Magento_Customer::manage',
+                                    ],
+                                ],
+                                'secure' => false,
+                            ],
+                        ],
+                    ],
+                ], \Magento\Customer\Api\CustomerRepositoryInterface::class => [
+                    'V1' => [
+                        'methods' => [
+                            'getById' => [
+                                'resources' => [
+                                    [
+                                        'Magento_Customer::customer',
+                                    ],
+                                ],
+                                'secure' => false,
+                            ],
+                        ],
+                    ],
+                ],
+            ],
+            'routes' => [
+                '/V1/customers/me/activate' => [
+                    'PUT' => [
+                        'secure' => false,
+                        'service' => [
+                            'class' => \Magento\Customer\Api\AccountManagementInterface::class,
+                            'method' => 'activateById',
+                        ],
+                        'resources' => [
+                            'self' => true,
+                        ],
+                        'parameters' => [
+                            'customerId' => [
+                                'force' => true,
+                                'value' => '%customer_id%',
+                            ],
+                        ],
+                    ],
+                ],
+                '/V1/customers/:customerId' => [
+                    'GET' => [
+                        'secure' => false,
+                        'service' => [
+                            'class' => \Magento\Customer\Api\CustomerRepositoryInterface::class,
+                            'method' => 'getById',
+                        ],
+                        'resources' => [
+                            'Magento_Customer::customer' => true,
+                        ],
+                        'parameters' => [
+                        ],
+                    ],
+                ],
+            ]
+        ];
+
+        /**
+         * @var $cacheMock \Magento\Webapi\Model\Cache\Type\Webapi
+         */
+        $cacheMock = $this->getMockBuilder(\Magento\Webapi\Model\Cache\Type\Webapi::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        /** @var $readerMock \Magento\Webapi\Model\Config\Reader */
+        $readerMock = $this->getMockBuilder(\Magento\Webapi\Model\Config\Reader::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $readerMock->expects($this->any())->method('read')->will($this->returnValue($servicesConfig));
+
+        $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+
+        /** @var $config \Magento\Webapi\Model\Config */
+        $config = $objectManager->create(
+            \Magento\Webapi\Model\Config::class,
+            [
+                'cache' => $cacheMock,
+                'configReader' => $readerMock,
+            ]
+        );
+
+        $typeProcessor = $objectManager->create(\Magento\Framework\Reflection\TypeProcessor::class);
+
+        /** @var $config \Magento\Webapi\Model\ServiceMetadata */
+        $this->serviceMetadata = $objectManager->create(
+            \Magento\Webapi\Model\ServiceMetadata::class,
+            [
+                'config' => $config,
+                'cache' => $cacheMock,
+                'classReflector' => $classReflection,
+                'typeProcessor' => $typeProcessor,
+            ]
+        );
+    }
+
+    public function testGetServiceMetadata()
+    {
+        $expectedResult = [
+            'methods' => [
+                'activateById' => [
+                    'method' => 'activateById',
+                    'inputRequired' => '',
+                    'isSecure' => '',
+                    'resources' => [['Magento_Customer::manage']],
+                    'interface' => [
+                        'in' => [
+                            'parameters' => [
+                                'customerId' => [
+                                    'force' => true,
+                                    'value' => '%customer_id%',
+                                ],
+                                'requiredInputParameter' => [
+                                    'required' => true,
+                                ],
+                            ],
+                        ],
+                        'out' => [
+                            'parameters' => [
+                                'outputParameter' => [
+                                    'type' => 'string',
+                                ],
+                            ],
+                        ],
+                    ],
+                ],
+            ],
+            'class' => \Magento\Customer\Api\AccountManagementInterface::class,
+            'description' => 'classDescription',
+        ];
+        $result = $this->serviceMetadata->getServiceMetadata('customerAccountManagementV1');
+        $this->assertEquals($expectedResult, $result);
+    }
+
+    public function testGetRouteMetadata()
+    {
+        $expectedResult = [
+            'methods' => [
+                'activateById' => [
+                    'method' => 'activateById',
+                    'inputRequired' => '',
+                    'isSecure' => '',
+                    'resources' => [['Magento_Customer::manage']],
+                    'interface' => [
+                        'in' => [
+                            'parameters' => [
+                                'customerId' => [
+                                    'force' => true,
+                                    'value' => '%customer_id%',
+                                ],
+                                'requiredInputParameter' => [
+                                    'required' => true,
+                                ],
+                            ],
+                        ],
+                        'out' => [
+                            'parameters' => [
+                                'outputParameter' => [
+                                    'type' => 'string',
+                                ],
+                            ],
+                        ],
+                    ],
+                ],
+            ],
+            'class' => \Magento\Customer\Api\AccountManagementInterface::class,
+            'description' => 'classDescription',
+            'routes' => [
+                '/V1/customers/me/activate' => [
+                    'PUT' => [
+                        'method' => 'activateById',
+                        'parameters' => [
+                            'customerId' => [
+                                'force' => true,
+                                'value' => '%customer_id%'
+                            ]
+                        ]
+                    ]
+                ]
+            ]
+        ];
+        $result = $this->serviceMetadata->getRouteMetadata('customerAccountManagementV1');
+        $this->assertEquals($expectedResult, $result);
+    }
+}