diff --git src/wp-includes/class-wp-customize-nav-menus.php src/wp-includes/class-wp-customize-nav-menus.php
index b01cf73..247f985 100644
--- src/wp-includes/class-wp-customize-nav-menus.php
+++ src/wp-includes/class-wp-customize-nav-menus.php
@@ -80,20 +80,41 @@ final class WP_Customize_Nav_Menus {
 		}
 
 		$obj_type = sanitize_key( $_POST['obj_type'] );
-		if ( ! in_array( $obj_type, array( 'post_type', 'taxonomy' ) ) ) {
-			wp_send_json_error( 'nav_menus_invalid_obj_type' );
+		$obj_name = sanitize_key( $_POST['type'] );
+		$page = empty( $_POST['page'] ) ? 0 : absint( $_POST['page'] );
+		$items = $this->load_available_items_query( $obj_type, $obj_name, $page );
+
+		if ( is_wp_error( $items ) ) {
+			wp_send_json_error( $items->get_error_code() );
+		} else {
+			wp_send_json_success( array( 'items' => $items ) );
 		}
+	}
 
-		$taxonomy_or_post_type = sanitize_key( $_POST['type'] );
-		$page = isset( $_POST['page'] ) ? absint( $_POST['page'] ) : 0;
+	/**
+	 * Performs the post_type and taxonomy queries for loading available menu items.
+	 *
+	 * @since 4.3.0
+	 * @access public
+	 *
+	 * @param string $obj_type Optional. Accepts 'post_type' or 'taxonomy'. Default is 'post_type'.
+	 * @param string $obj_name Optional. Accepts any registered taxonomy or post type name. Default is 'page'.
+	 * @param int    $page     Optional. The page number used to generate the query offset. Default is '0'.
+	 * @return WP_Error|array Returns either a WP_Error object or an array of menu items.
+	 */
+	public function load_available_items_query( $obj_type = 'post_type', $obj_name = 'page', $page = 0 ) {
 		$items = array();
 
+		if ( ! in_array( $obj_type, array( 'post_type', 'taxonomy' ) ) ) {
+			return new WP_Error( 'nav_menus_invalid_obj_type' );
+		}
+
 		if ( 'post_type' === $obj_type ) {
-			if ( ! get_post_type_object( $taxonomy_or_post_type ) ) {
-				wp_send_json_error( 'nav_menus_invalid_post_type' );
+			if ( ! get_post_type_object( $obj_name ) ) {
+				return new WP_Error( 'nav_menus_invalid_post_type' );
 			}
 
-			if ( 0 === $page && 'page' === $taxonomy_or_post_type ) {
+			if ( 0 === $page && 'page' === $obj_name ) {
 				// Add "Home" link. Treat as a page, but switch to custom on add.
 				$items[] = array(
 					'id'         => 'home',
@@ -110,7 +131,7 @@ final class WP_Customize_Nav_Menus {
 				'offset'      => 10 * $page,
 				'orderby'     => 'date',
 				'order'       => 'DESC',
-				'post_type'   => $taxonomy_or_post_type,
+				'post_type'   => $obj_name,
 			) );
 			foreach ( $posts as $post ) {
 				$post_title = $post->post_title;
@@ -129,7 +150,7 @@ final class WP_Customize_Nav_Menus {
 				);
 			}
 		} elseif ( 'taxonomy' === $obj_type ) {
-			$terms = get_terms( $taxonomy_or_post_type, array(
+			$terms = get_terms( $obj_name, array(
 				'child_of'     => 0,
 				'exclude'      => '',
 				'hide_empty'   => false,
@@ -142,7 +163,7 @@ final class WP_Customize_Nav_Menus {
 				'pad_counts'   => false,
 			) );
 			if ( is_wp_error( $terms ) ) {
-				wp_send_json_error( $terms->get_error_code() );
+				return $terms;
 			}
 
 			foreach ( $terms as $term ) {
@@ -158,7 +179,7 @@ final class WP_Customize_Nav_Menus {
 			}
 		}
 
-		wp_send_json_success( array( 'items' => $items ) );
+		return $items;
 	}
 
 	/**
@@ -184,12 +205,12 @@ final class WP_Customize_Nav_Menus {
 		}
 
 		$s = sanitize_text_field( wp_unslash( $_POST['search'] ) );
-		$results = $this->search_available_items_query( array( 'pagenum' => $p, 's' => $s ) );
+		$items = $this->search_available_items_query( array( 'pagenum' => $p, 's' => $s ) );
 
-		if ( empty( $results ) ) {
-			wp_send_json_error( array( 'message' => __( 'No results found.' ) ) );
+		if ( empty( $items ) ) {
+			wp_send_json_error( array( 'message' => __( 'No menu items found.' ) ) );
 		} else {
-			wp_send_json_success( array( 'items' => $results ) );
+			wp_send_json_success( array( 'items' => $items ) );
 		}
 	}
 
@@ -202,10 +223,10 @@ final class WP_Customize_Nav_Menus {
 	 * @access public
 	 *
 	 * @param array $args Optional. Accepts 'pagenum' and 's' (search) arguments.
-	 * @return array Results.
+	 * @return array Menu items.
 	 */
 	public function search_available_items_query( $args = array() ) {
-		$results = array();
+		$items = array();
 
 		$post_type_objects = get_post_types( array( 'show_in_nav_menus' => true ), 'objects' );
 		$query = array(
@@ -235,7 +256,7 @@ final class WP_Customize_Nav_Menus {
 					/* translators: %d: ID of a post */
 					$post_title = sprintf( __( '#%d (no title)' ), $post->ID );
 				}
-				$results[] = array(
+				$items[] = array(
 					'id'         => 'post-' . $post->ID,
 					'title'      => html_entity_decode( $post_title, ENT_QUOTES, get_bloginfo( 'charset' ) ),
 					'type'       => 'post_type',
@@ -258,7 +279,7 @@ final class WP_Customize_Nav_Menus {
 		// Check if any taxonomies were found.
 		if ( ! empty( $terms ) ) {
 			foreach ( $terms as $term ) {
-				$results[] = array(
+				$items[] = array(
 					'id'         => 'term-' . $term->term_id,
 					'title'      => html_entity_decode( $term->name, ENT_QUOTES, get_bloginfo( 'charset' ) ),
 					'type'       => 'taxonomy',
@@ -270,7 +291,7 @@ final class WP_Customize_Nav_Menus {
 			}
 		}
 
-		return $results;
+		return $items;
 	}
 
 	/**
diff --git tests/phpunit/tests/ajax/CustomizeMenus.php tests/phpunit/tests/ajax/CustomizeMenus.php
new file mode 100644
index 0000000..b99f0f5
--- /dev/null
+++ tests/phpunit/tests/ajax/CustomizeMenus.php
@@ -0,0 +1,548 @@
+<?php
+/**
+ * Testing ajax customize menus functionality
+ *
+ * @package    WordPress
+ * @subpackage UnitTests
+ * @since      4.3.0
+ * @group      ajax
+ * @runTestsInSeparateProcesses
+ */
+class Tests_Ajax_CustomizeMenus extends WP_Ajax_UnitTestCase {
+
+	/**
+	 * Instance of WP_Customize_Manager which is reset for each test.
+	 *
+	 * @var WP_Customize_Manager
+	 */
+	public $wp_customize;
+
+	/**
+	 * Set up the test fixture.
+	 */
+	public function setUp() {
+		parent::setUp();
+		require_once ABSPATH . WPINC . '/class-wp-customize-manager.php';
+		wp_set_current_user( $this->factory->user->create( array( 'role' => 'administrator' ) ) );
+		global $wp_customize;
+		$this->wp_customize = new WP_Customize_Manager();
+		$wp_customize = $this->wp_customize;
+	}
+
+	/**
+	 * Tear down the test fixture.
+	 */
+	public function tearDown() {
+		wp_set_current_user( 0 );
+		parent::tearDown();
+	}
+
+	/**
+	 * Helper to keep it DRY
+	 * @param $action
+	 */
+	protected function make_ajax_call( $action ) {
+		// Make the request.
+		try {
+			$this->_handleAjax( $action );
+		} catch ( WPAjaxDieContinueException $e ) {
+			unset( $e );
+		}
+	}
+
+	/**
+	 * Testing capabilities check for ajax_load_available_items method
+	 *
+	 * @dataProvider data_ajax_load_available_items_cap_check
+	 *
+	 * @param string $role The role we're checking caps against
+	 * @param array $expected_results
+	 */
+	function test_ajax_load_available_items_cap_check( $role, $expected_results ) {
+
+		if ( 'administrator' != $role ) {
+			// If we're not an admin, we should get a wp_die(-1).
+			$this->setExpectedException( 'WPAjaxDieStopException' );
+		}
+
+		wp_set_current_user( $this->factory->user->create( array( 'role' => $role ) ) );
+
+		$_POST = array(
+			'action'                => 'load-available-menu-items-customizer',
+			'customize-menus-nonce' => wp_create_nonce( 'customize-menus' ),
+		);
+
+		$this->make_ajax_call( 'load-available-menu-items-customizer' );
+
+		// If we are an admin, we should get a proper response.
+		if ( 'administrator' === $role ) {
+			// Get the results.
+			$response = json_decode( $this->_last_response, true );
+
+			$this->assertSame( $expected_results, $response );
+		}
+
+	}
+
+	/**
+	 *
+	 * Data provider.
+	 *
+	 * Provides various post_args to induce error messages in the that can be
+	 * compared to the expected_results.
+	 *
+	 * @since 4.3.0
+	 *
+	 * @return array {
+	 *     @type array {
+	 *         @string string $role             The role that will test caps for.
+	 *         @array  array  $expected_results The expected results from the ajax call.
+	 *     }
+	 * }
+	 *
+	 */
+	function data_ajax_load_available_items_cap_check() {
+		return array(
+			array(
+				'subscriber',
+				array(),
+			),
+			array(
+				'contributor',
+				array(),
+			),
+			array(
+				'author',
+				array(),
+			),
+			array(
+				'editor',
+				array(),
+			),
+			array(
+				'administrator',
+				array(
+					'success' => false,
+					'data'    => 'nav_menus_missing_obj_type_or_type_parameter',
+				),
+			),
+		);
+	}
+
+	/**
+	 * Testing the error messaging for ajax_load_available_items
+	 *
+	 * @dataProvider data_ajax_load_available_items_error_messages
+	 *
+	 */
+	function test_ajax_load_available_items_error_messages( $post_args, $expected_results ) {
+
+		$_POST = array_merge( array(
+			'action'                => 'load-available-menu-items-customizer',
+			'customize-menus-nonce' => wp_create_nonce( 'customize-menus' ),
+		), $post_args );
+
+		// Make the request.
+		$this->make_ajax_call( 'load-available-menu-items-customizer' );
+
+		// Get the results.
+		$response = json_decode( $this->_last_response, true );
+
+		$this->assertSame( $expected_results, $response );
+	}
+
+	/**
+	 *
+	 * Data provider.
+	 *
+	 * Provides various post_args to induce error messages in the that can be
+	 * compared to the expected_results.
+	 *
+	 * @since 4.3.0
+	 *
+	 * @return array {
+	 *     @type array {
+	 *         @array array $post_args        The arguments that will merged with the $_POST array.
+	 *         @array array $expected_results The expected results from the ajax call.
+	 *     }
+	 * }
+	 *
+	 */
+	function data_ajax_load_available_items_error_messages() {
+		return array(
+			// Testing empty obj_type and type.
+			array(
+				array(
+					'obj_type' => '',
+					'type'     => '',
+				),
+				array(
+					'success'  => false,
+					'data'     => 'nav_menus_missing_obj_type_or_type_parameter',
+				),
+			),
+			// Testing empty obj_type.
+			array(
+				array(
+					'obj_type' => '',
+					'type'     => 'post',
+				),
+				array(
+					'success'  => false,
+					'data'     => 'nav_menus_missing_obj_type_or_type_parameter',
+				),
+			),
+			// Testing empty type.
+			array(
+				array(
+					'obj_type' => '',
+					'type'     => 'post',
+				),
+				array(
+					'success'  => false,
+					'data'     => 'nav_menus_missing_obj_type_or_type_parameter',
+				),
+			),
+			// Testing incorrect obj_type option.
+			array(
+				array(
+					'obj_type' => 'invalid',
+					'type'     => 'post',
+				),
+				array(
+					'success'  => false,
+					'data'     => 'nav_menus_invalid_obj_type',
+				),
+			),
+			// Testing incorrect type option.
+			array(
+				array(
+					'obj_type' => 'post_type',
+					'type'     => 'invalid',
+				),
+				array(
+					'success'  => false,
+					'data'     => 'nav_menus_invalid_post_type',
+				),
+			),
+		);
+	}
+
+	/**
+	 * Testing the success status
+	 *
+	 * @dataProvider data_ajax_load_available_items_sucess_status
+	 */
+	function test_ajax_load_available_items_sucess_status( $post_args, $success_status ) {
+
+		$_POST = array_merge( array(
+			'action'                => 'load-available-menu-items-customizer',
+			'customize-menus-nonce' => wp_create_nonce( 'customize-menus' ),
+		), $post_args );
+
+		// Make the request.
+		$this->make_ajax_call( 'load-available-menu-items-customizer' );
+
+		// Get the results.
+		$response = json_decode( $this->_last_response, true );
+		$this->assertSame( $success_status, $response['success'] );
+
+	}
+
+	/**
+	 *
+	 * Data provider.
+	 *
+	 * Provides various post_args to retrieve results and compare against
+	 * the success status.
+	 *
+	 * @since 4.3.0
+	 *
+	 * @return array {
+	 *     @type array {
+	 *         @type array $post_args      The arguments that will merged with the $_POST array.
+	 *         @type bool  $success_status The expected success status.
+	 *     }
+	 * }
+	 *
+	 */
+	function data_ajax_load_available_items_sucess_status() {
+		return array(
+			array(
+				array(
+					'obj_type' => 'post_type',
+					'type'     => 'post',
+				),
+				true,
+			),
+			array(
+				array(
+					'obj_type' => 'post_type',
+					'type'     => 'page',
+				),
+				true,
+			),
+			array(
+				array(
+					'obj_type' => 'post_type',
+					'type'     => 'custom',
+				),
+				false,
+			),
+			array(
+				array(
+					'obj_type' => 'taxonomy',
+					'type'     => 'post_tag',
+				),
+				true,
+			),
+		);
+	}
+
+	/**
+	 * Testing the array structure for a single item
+	 *
+	 * @dataProvider data_ajax_load_available_items_structure
+	 *
+	 */
+	function test2_ajax_load_available_items_structure( $post_args ) {
+
+		$expected_keys = array(
+			'id',
+			'title',
+			'type',
+			'type_label',
+			'object',
+			'object_id',
+			'url',
+		);
+
+		// Create some terms and pages.
+		$this->factory->term->create_many( 5 );
+		$this->factory->post->create_many( 5, array( 'post_type' => 'page' ) );
+
+		$_POST = array_merge( array(
+			'action'                => 'load-available-menu-items-customizer',
+			'customize-menus-nonce' => wp_create_nonce( 'customize-menus' ),
+		), $post_args );
+
+		// Make the request.
+		$this->make_ajax_call( 'load-available-menu-items-customizer' );
+
+		// Get the results.
+		$response = json_decode( $this->_last_response, true );
+
+		$this->assertNotEmpty( $response['data']['items'] );
+
+		// Get the second index to avoid the home page edge case.
+		$test_item = $response['data']['items'][1];
+
+		foreach ( $expected_keys as $key ) {
+			$this->assertArrayHasKey( $key, $test_item );
+			$this->assertNotEmpty( $test_item[ $key ] );
+		}
+
+		// Special test for the home page.
+		if ( 'page' === $test_item['object'] ) {
+			$home = $response['data']['items'][0];
+			foreach ( $expected_keys as $key ) {
+				if ( 'object_id' !== $key ){
+					$this->assertArrayHasKey( $key, $home );
+					if ( 'object' !== $key ) {
+						$this->assertNotEmpty( $home[ $key ] );
+					}
+				}
+			}
+		}
+	}
+
+	/**
+	 *
+	 * Data provider.
+	 *
+	 * Provides various post_args to return a list of items to test the array structure of.
+	 *
+	 * @since 4.3.0
+	 *
+	 * @return array {
+	 *     @type array {
+	 *         @type array $post_args The arguments that will merged with the $_POST array.
+	 *     }
+	 * }
+	 *
+	 */
+	function data_ajax_load_available_items_structure() {
+		return array(
+			array(
+				array(
+					'obj_type' => 'post_type',
+					'type'     => 'post',
+				),
+			),
+			array(
+				array(
+					'obj_type' => 'post_type',
+					'type'     => 'page',
+				),
+			),
+			array(
+				array(
+					'obj_type' => 'taxonomy',
+					'type'     => 'post_tag',
+				),
+			),
+		);
+	}
+
+	/**
+	 * Testing the error messages for ajax_search_available_items
+	 *
+	 * @dataProvider data_ajax_search_available_items_caps_check
+	 */
+	function test_ajax_search_available_items_caps_check( $role, $expected_results ) {
+
+		if ( 'administrator' != $role ) {
+			// If we're not an admin, we should get a wp_die(-1).
+			$this->setExpectedException( 'WPAjaxDieStopException' );
+		}
+
+		wp_set_current_user( $this->factory->user->create( array( 'role' => $role ) ) );
+
+		$_POST = array(
+			'action'                => 'search-available-menu-items-customizer',
+			'customize-menus-nonce' => wp_create_nonce( 'customize-menus' ),
+		);
+
+		$this->make_ajax_call( 'search-available-menu-items-customizer' );
+
+		// If we are an admin, we should get a proper response.
+		if ( 'administrator' === $role ) {
+			// Get the results.
+			$response = json_decode( $this->_last_response, true );
+
+			$this->assertSame( $expected_results, $response );
+		}
+	}
+
+	/**
+	 *
+	 * Data provider.
+	 *
+	 * Provides various post_args to induce error messages in the that can be
+	 * compared to the expected_results.
+	 *
+	 * @since 4.3.0
+	 *
+	 * @todo Make this more DRY
+	 *
+	 * @return array {
+	 *     @type array {
+	 *         @string string $role             The role that will test caps for.
+	 *         @array  array  $expected_results The expected results from the ajax call.
+	 *     }
+	 * }
+	 *
+	 */
+	function data_ajax_search_available_items_caps_check() {
+		return array(
+			array(
+				'subscriber',
+				array(),
+			),
+			array(
+				'contributor',
+				array(),
+			),
+			array(
+				'author',
+				array(),
+			),
+			array(
+				'editor',
+				array(),
+			),
+			array(
+				'administrator',
+				array(
+					'success' => false,
+					'data'    => 'nav_menus_missing_search_parameter',
+				),
+			),
+		);
+	}
+
+	/**
+	 * Testing the results of various searches
+	 *
+	 * @dataProvider data_ajax_search_available_items_results
+	 */
+	function test_ajax_search_available_items_results( $post_args, $expected_results ) {
+
+		$this->factory->post->create_many( 5, array( 'post_title' => 'Test Post' ) );
+
+		$_POST = array_merge( array(
+			'action'                => 'search-available-menu-items-customizer',
+			'customize-menus-nonce' => wp_create_nonce( 'customize-menus' ),
+		), $post_args );
+
+		$this->make_ajax_call( 'search-available-menu-items-customizer' );
+
+		$response = json_decode( $this->_last_response, true );
+
+		if ( isset( $post_args['search'] ) && 'test' === $post_args['search'] ) {
+			$this->assertsame( true, $response['success'] );
+			$this->assertSame( 5, count( $response['data']['items'] ) );
+		} else {
+			$this->assertSame( $expected_results, $response );
+		}
+
+	}
+
+	/**
+	 *
+	 * Data provider.
+	 *
+	 * Provides various post_args to test the results.
+	 *
+	 * @since 4.3.0
+	 *
+	 * @return array {
+	 *     @type array {
+	 *         @string string $post_args        The args that will be passed to ajax.
+	 *         @array  array  $expected_results The expected results from the ajax call.
+	 *     }
+	 * }
+	 *
+	 */
+	function data_ajax_search_available_items_results() {
+		return array(
+			array(
+				array(),
+				array(
+					'success' => false,
+					'data'    => 'nav_menus_missing_search_parameter',
+				),
+			),
+			array(
+				array(
+					'search'  => 'all_the_things',
+				),
+				array(
+					'success' => false,
+					'data'    => array(
+						'message' => 'No menu items found.',
+					),
+				),
+			),
+			array(
+				array(
+					'search'  => 'test',
+				),
+				array(
+					'success' => true,
+					array(),
+				),
+			),
+		);
+	}
+}
diff --git tests/phpunit/tests/customize/nav-menus.php tests/phpunit/tests/customize/nav-menus.php
index 7fa88e7..27c216e 100644
--- tests/phpunit/tests/customize/nav-menus.php
+++ tests/phpunit/tests/customize/nav-menus.php
@@ -49,25 +49,163 @@ class Test_WP_Customize_Nav_Menus extends WP_UnitTestCase {
 	}
 
 	/**
-	 * Test the test_load_available_items_ajax method.
+	 * Test that the load_available_items_query method returns a WP_Error object.
 	 *
-	 * @see WP_Customize_Nav_Menus::load_available_items_ajax()
+	 * @see WP_Customize_Nav_Menus::load_available_items_query()
 	 */
-	function test_load_available_items_ajax() {
+	function test_load_available_items_query_returns_wp_error() {
+		$menus = new WP_Customize_Nav_Menus( $this->wp_customize );
+
+		// Invalid $obj_type.
+		$items = $menus->load_available_items_query( 'invalid' );
+		$this->assertInstanceOf( 'WP_Error', $items );
+
+		// Invalid post type $obj_name.
+		$items = $menus->load_available_items_query( 'post_type', 'invalid' );
+		$this->assertInstanceOf( 'WP_Error', $items );
+
+		// Invalid taxonomy $obj_name.
+		$items = $menus->load_available_items_query( 'taxonomy', 'invalid' );
+		$this->assertInstanceOf( 'WP_Error', $items );
+	}
+
+	/**
+	 * Test the load_available_items_query method maybe returns the home page item.
+	 *
+	 * @see WP_Customize_Nav_Menus::load_available_items_query()
+	 */
+	function test_load_available_items_query_maybe_returns_home() {
+		$menus = new WP_Customize_Nav_Menus( $this->wp_customize );
+
+		// Expected menu item array.
+		$expected = array(
+			'id'         => 'home',
+			'title'      => _x( 'Home', 'nav menu home label' ),
+			'type'       => 'custom',
+			'type_label' => __( 'Custom Link' ),
+			'object'     => '',
+			'url'        => home_url(),
+		);
+
+		// Create pages.
+		$this->factory->post->create_many( 15, array( 'post_type' => 'page' ) );
+
+		// Home is included in menu items when page is zero.
+		$items = $menus->load_available_items_query( 'post_type', 'page', 0 );
+		$this->assertContains( $expected, $items );
+
+		// Home is not included in menu items when page is larger than zero.
+		$items = $menus->load_available_items_query( 'post_type', 'page', 1 );
+		$this->assertNotEmpty( $items );
+		$this->assertNotContains( $expected, $items );
+	}
+
+	/**
+	 * Test the load_available_items_query method returns post item.
+	 *
+	 * @see WP_Customize_Nav_Menus::load_available_items_query()
+	 */
+	function test_load_available_items_query_returns_post_item_with_page_number() {
+		$menus = new WP_Customize_Nav_Menus( $this->wp_customize );
+
+		// Create page.
+		$post_id = $this->factory->post->create( array( 'post_title' => 'Post Title' ) );
+
+		// Create pages.
+		$this->factory->post->create_many( 10 );
+
+		// Expected menu item array.
+		$expected = array(
+			'id'         => "post-{$post_id}",
+			'title'      => 'Post Title',
+			'type'       => 'post_type',
+			'type_label' => 'Post',
+			'object'     => 'post',
+			'object_id'  => intval( $post_id ),
+			'url'        => get_permalink( intval( $post_id ) ),
+		);
+
+		// Offset the query and get the second page of menu items.
+		$items = $menus->load_available_items_query( 'post_type', 'post', 1 );
+		$this->assertContains( $expected, $items );
+	}
 
-		$this->markTestIncomplete( 'This test has not been implemented.' );
+	/**
+	 * Test the load_available_items_query method returns page item.
+	 *
+	 * @see WP_Customize_Nav_Menus::load_available_items_query()
+	 */
+	function test_load_available_items_query_returns_page_item() {
+		$menus = new WP_Customize_Nav_Menus( $this->wp_customize );
+
+		// Create page.
+		$page_id = $this->factory->post->create( array( 'post_title' => 'Page Title', 'post_type' => 'page' ) );
+
+		// Expected menu item array.
+		$expected = array(
+			'id'         => "post-{$page_id}",
+			'title'      => 'Page Title',
+			'type'       => 'post_type',
+			'type_label' => 'Page',
+			'object'     => 'page',
+			'object_id'  => intval( $page_id ),
+			'url'        => get_permalink( intval( $page_id ) ),
+		);
 
+		$items = $menus->load_available_items_query( 'post_type', 'page', 0 );
+		$this->assertContains( $expected, $items );
 	}
 
 	/**
-	 * Test the search_available_items_ajax method.
+	 * Test the load_available_items_query method returns post item.
 	 *
-	 * @see WP_Customize_Nav_Menus::search_available_items_ajax()
+	 * @see WP_Customize_Nav_Menus::load_available_items_query()
 	 */
-	function test_search_available_items_ajax() {
+	function test_load_available_items_query_returns_post_item() {
+		$menus = new WP_Customize_Nav_Menus( $this->wp_customize );
+
+		// Create post.
+		$post_id = $this->factory->post->create( array( 'post_title' => 'Post Title' ) );
 
-		$this->markTestIncomplete( 'This test has not been implemented.' );
+		// Expected menu item array.
+		$expected = array(
+			'id'         => "post-{$post_id}",
+			'title'      => 'Post Title',
+			'type'       => 'post_type',
+			'type_label' => 'Post',
+			'object'     => 'post',
+			'object_id'  => intval( $post_id ),
+			'url'        => get_permalink( intval( $post_id ) ),
+		);
 
+		$items = $menus->load_available_items_query( 'post_type', 'post', 0 );
+		$this->assertContains( $expected, $items );
+	}
+
+	/**
+	 * Test the load_available_items_query method returns term item.
+	 *
+	 * @see WP_Customize_Nav_Menus::load_available_items_query()
+	 */
+	function test_load_available_items_query_returns_term_item() {
+		$menus = new WP_Customize_Nav_Menus( $this->wp_customize );
+
+		// Create term.
+		$term_id = $this->factory->category->create( array( 'name' => 'Term Title' ) );
+
+		// Expected menu item array.
+		$expected = array(
+			'id'         => "term-{$term_id}",
+			'title'      => 'Term Title',
+			'type'       => 'taxonomy',
+			'type_label' => 'Category',
+			'object'     => 'category',
+			'object_id'  => intval( $term_id ),
+			'url'        => get_term_link( intval( $term_id ), 'category' ),
+		);
+
+		$items = $menus->load_available_items_query( 'taxonomy', 'category', 0 );
+		$this->assertContains( $expected, $items );
 	}
 
 	/**
@@ -454,14 +592,4 @@ class Test_WP_Customize_Nav_Menus extends WP_UnitTestCase {
 
 	}
 
-	/**
-	 * Test the render_menu method.
-	 *
-	 * @see WP_Customize_Nav_Menus::render_menu()
-	 */
-	function test_render_menu() {
-
-		$this->markTestIncomplete( 'This test has not been implemented.' );
-	}
-
 }
