diff --git a/apps/mappingmanagement/api/src/test/java/org/onosproject/mapping/instructions/MappingInstructionsTest.java b/apps/mappingmanagement/api/src/test/java/org/onosproject/mapping/instructions/MappingInstructionsTest.java
index 5bf628d..e11022c 100644
--- a/apps/mappingmanagement/api/src/test/java/org/onosproject/mapping/instructions/MappingInstructionsTest.java
+++ b/apps/mappingmanagement/api/src/test/java/org/onosproject/mapping/instructions/MappingInstructionsTest.java
@@ -15,8 +15,452 @@
  */
 package org.onosproject.mapping.instructions;
 
+import com.google.common.testing.EqualsTester;
+import org.junit.Test;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.flow.instructions.ExtensionPropertyException;
+import org.onosproject.net.flow.instructions.ExtensionTreatment;
+import org.onosproject.net.flow.instructions.ExtensionTreatmentType;
+
+import java.util.List;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.instanceOf;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.not;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
+import static org.onlab.junit.UtilityClassChecker.assertThatClassIsUtility;
+
 /**
  * Unit tests for the MappingInstructions class.
  */
 public class MappingInstructionsTest {
+
+    /**
+     * Checks that a MappingInstruction object has the proper type, ad then
+     * converts it to the proper type.
+     *
+     * @param instruction MappingInstruction object to convert
+     * @param type        Enumerated type value for the Criterion class
+     * @param clazz       Desired Criterion class
+     * @param <T>         The type the caller wants returned
+     * @return converted object
+     */
+    @SuppressWarnings("unchecked")
+    private <T> T checkAndConvert(MappingInstruction instruction,
+                                  MappingInstruction.Type type, Class clazz) {
+        assertThat(instruction, is(notNullValue()));
+        assertThat(instruction.type(), is(equalTo(type)));
+        assertThat(instruction, instanceOf(clazz));
+        return (T) instruction;
+    }
+
+    /**
+     * Checks the equals() and toString() methods of a MappingInstruction class.
+     *
+     * @param c1      first object to compare
+     * @param c1match object that should be equal to the first
+     * @param c2      object that should not be equal to the first
+     * @param <T>     type of the arguments
+     */
+    private <T extends MappingInstruction> void checkEqualsAndToString(T c1,
+                                                                       T c1match,
+                                                                       T c2) {
+        new EqualsTester()
+                .addEqualityGroup(c1, c1match)
+                .addEqualityGroup(c2)
+                .testEquals();
+    }
+
+    /**
+     * Checks that MappingInstructions is a proper utility class.
+     */
+    @Test
+    public void testMappingInstructionsUtilityClass() {
+        assertThatClassIsUtility(MappingInstructions.class);
+    }
+
+    /**
+     * Checks that the MappingInstruction class implementation are immutable.
+     */
+    @Test
+    public void testImmutabilityOfMappingInstructions() {
+        assertThatClassIsImmutable(ActionMappingInstruction.NoActionMappingInstruction.class);
+        assertThatClassIsImmutable(ActionMappingInstruction.NativeForwardMappingInstruction.class);
+        assertThatClassIsImmutable(ActionMappingInstruction.ForwardMappingInstruction.class);
+        assertThatClassIsImmutable(ActionMappingInstruction.DropMappingInstruction.class);
+        assertThatClassIsImmutable(MulticastMappingInstruction.WeightMappingInstruction.class);
+        assertThatClassIsImmutable(MulticastMappingInstruction.PriorityMappingInstruction.class);
+        assertThatClassIsImmutable(UnicastMappingInstruction.WeightMappingInstruction.class);
+        assertThatClassIsImmutable(UnicastMappingInstruction.PriorityMappingInstruction.class);
+    }
+
+    private final ActionMappingInstruction noAction1 = MappingInstructions.noAction();
+    private final ActionMappingInstruction noAction2 = MappingInstructions.noAction();
+
+    /**
+     * Tests the noAction method.
+     */
+    @Test
+    public void testNoActionMethod() {
+        ActionMappingInstruction instruction = MappingInstructions.noAction();
+        checkAndConvert(instruction,
+                        ActionMappingInstruction.Type.ACTION,
+                        ActionMappingInstruction.NoActionMappingInstruction.class);
+    }
+
+    /**
+     * Tests the equals() method of the NoActionMappingInstruction class.
+     */
+    @Test
+    public void testNoActionMappingInstructionEquals() {
+        new EqualsTester()
+                .addEqualityGroup(noAction1, noAction2)
+                .testEquals();
+    }
+
+    /**
+     * Tests the hashCode() method of the NoActionMappingInstruction class.
+     */
+    @Test
+    public void testNoActionMappingInstructionHashCode() {
+        assertThat(noAction1.hashCode(), is(equalTo(noAction2.hashCode())));
+    }
+
+    private final ActionMappingInstruction fwdAction1 = MappingInstructions.forwardAction();
+    private final ActionMappingInstruction fwdAction2 = MappingInstructions.forwardAction();
+
+    /**
+     * Tests the forwardAction method.
+     */
+    @Test
+    public void testForwardActionMethod() {
+        ActionMappingInstruction instruction = MappingInstructions.forwardAction();
+        checkAndConvert(instruction,
+                        ActionMappingInstruction.Type.ACTION,
+                        ActionMappingInstruction.ForwardMappingInstruction.class);
+    }
+
+    /**
+     * Tests the equals() method of the ForwardActionMappingInstruction class.
+     */
+    @Test
+    public void testForwardActionMappingInstructionEquals() {
+        new EqualsTester()
+                .addEqualityGroup(fwdAction1, fwdAction2)
+                .testEquals();
+    }
+
+    /**
+     * Tests the hashCode() method of the ForwardActionMappingInstruction class.
+     */
+    @Test
+    public void testForwardActionMappingInstructionHashCode() {
+        assertThat(fwdAction1.hashCode(), is(equalTo(fwdAction2.hashCode())));
+    }
+
+    private final ActionMappingInstruction nativeFwdAction1 =
+                                            MappingInstructions.nativeForwardAction();
+    private final ActionMappingInstruction nativeFwdAction2 =
+                                            MappingInstructions.nativeForwardAction();
+
+    /**
+     * Tests the nativeForwardAction method.
+     */
+    @Test
+    public void testNativeForwardActionMethod() {
+        ActionMappingInstruction instruction = MappingInstructions.nativeForwardAction();
+        checkAndConvert(instruction,
+                        ActionMappingInstruction.Type.ACTION,
+                        ActionMappingInstruction.NativeForwardMappingInstruction.class);
+    }
+
+    /**
+     * Tests the equals() method of the NativeForwardActionMappingInstruction class.
+     */
+    @Test
+    public void testNativeForwardActionMappingInstructionEquals() {
+        new EqualsTester()
+                .addEqualityGroup(nativeFwdAction1, nativeFwdAction2)
+                .testEquals();
+    }
+
+    /**
+     * Tests the hashCode() method of the NativeForwardActionMappingInstruction class.
+     */
+    @Test
+    public void testNativeForwardActionMappingInstructionHashCode() {
+        assertThat(nativeFwdAction1.hashCode(), is(equalTo(nativeFwdAction2.hashCode())));
+    }
+
+    private final ActionMappingInstruction dropAction1 = MappingInstructions.dropAction();
+    private final ActionMappingInstruction dropAction2 = MappingInstructions.dropAction();
+
+    /**
+     * Tests the dropAction method.
+     */
+    @Test
+    public void testDropActionMethod() {
+        ActionMappingInstruction instruction = MappingInstructions.dropAction();
+        checkAndConvert(instruction,
+                        ActionMappingInstruction.Type.ACTION,
+                        ActionMappingInstruction.DropMappingInstruction.class);
+    }
+
+    /**
+     * Tests the equals() method of the DropActionMappingInstruction class.
+     */
+    @Test
+    public void testDropActionMappingInstructionEquals() {
+        new EqualsTester()
+                .addEqualityGroup(dropAction1, dropAction2)
+                .testEquals();
+    }
+
+    /**
+     * Tests the hashCode() method of the DropActionMappingInstruction class.
+     */
+    @Test
+    public void testDropActionMappingInstructionHashCode() {
+        assertThat(dropAction1.hashCode(), is(equalTo(dropAction2.hashCode())));
+    }
+
+    private final UnicastMappingInstruction uniWeight1 =
+                                    MappingInstructions.unicastWeight(1);
+    private final UnicastMappingInstruction sameAsUniWeight1 =
+                                    MappingInstructions.unicastWeight(1);
+    private final UnicastMappingInstruction uniWeight2 =
+                                    MappingInstructions.unicastWeight(2);
+
+    /**
+     * Tests the unicastWeight method.
+     */
+    @Test
+    public void testUnicastWeightMethod() {
+        final MappingInstruction instruction = MappingInstructions.unicastWeight(2);
+        final UnicastMappingInstruction.WeightMappingInstruction weightInstruction =
+                        checkAndConvert(instruction,
+                        UnicastMappingInstruction.Type.UNICAST,
+                        UnicastMappingInstruction.WeightMappingInstruction.class);
+        assertThat(weightInstruction.weight(), is(equalTo(2)));
+    }
+
+    /**
+     * Test the equals() method of the UnicastWeightInstruction class.
+     */
+    @Test
+    public void testUnicastWeightInstructionEquals() {
+        checkEqualsAndToString(uniWeight1, sameAsUniWeight1, uniWeight2);
+    }
+
+    /**
+     * Tests the hashCode() method of the UnicastWeightInstruction class.
+     */
+    @Test
+    public void testUnicastWeightInstructionHashCode() {
+        assertThat(uniWeight1.hashCode(), is(equalTo(sameAsUniWeight1.hashCode())));
+        assertThat(uniWeight1.hashCode(), is(not(equalTo(uniWeight2.hashCode()))));
+    }
+
+    private final UnicastMappingInstruction uniPriority1 =
+                                    MappingInstructions.unicastPriority(1);
+    private final UnicastMappingInstruction sameAsUniPriority1 =
+                                    MappingInstructions.unicastPriority(1);
+    private final UnicastMappingInstruction uniPriority2 =
+                                    MappingInstructions.unicastPriority(2);
+
+    /**
+     * Tests the unicastPriority method.
+     */
+    @Test
+    public void testUnicastPriorityMethod() {
+        final MappingInstruction instruction = MappingInstructions.unicastPriority(2);
+        final UnicastMappingInstruction.PriorityMappingInstruction priorityMappingInstruction =
+                checkAndConvert(instruction,
+                                UnicastMappingInstruction.Type.UNICAST,
+                                UnicastMappingInstruction.PriorityMappingInstruction.class);
+        assertThat(priorityMappingInstruction.priority(), is(equalTo(2)));
+    }
+
+    /**
+     * Tests the equals() method of the UnicastPriorityInstruction class.
+     */
+    @Test
+    public void testUnicastPriorityInstructionEquals() {
+        checkEqualsAndToString(uniPriority1, sameAsUniPriority1, uniPriority2);
+    }
+
+    /**
+     * Test the hashCode() method of the UnicastPriorityInstruction class.
+     */
+    @Test
+    public void testUnicastPriorityInstructionHashCode() {
+        assertThat(uniPriority1.hashCode(), is(equalTo(sameAsUniPriority1.hashCode())));
+        assertThat(uniPriority1.hashCode(), is(not(equalTo(uniPriority2.hashCode()))));
+    }
+
+    private final MulticastMappingInstruction multiWeight1 =
+                                    MappingInstructions.multicastWeight(1);
+    private final MulticastMappingInstruction sameAsMultiWeight1 =
+                                    MappingInstructions.multicastWeight(1);
+    private final MulticastMappingInstruction multiWeight2 =
+                                    MappingInstructions.multicastWeight(2);
+
+    /**
+     * Tests the multicastWeight method.
+     */
+    @Test
+    public void testMulticastWeightMethod() {
+        final MappingInstruction instruction = MappingInstructions.multicastWeight(2);
+        final MulticastMappingInstruction.WeightMappingInstruction weightMappingInstruction =
+                checkAndConvert(instruction,
+                                MulticastMappingInstruction.Type.MULTICAST,
+                                MulticastMappingInstruction.WeightMappingInstruction.class);
+        assertThat(weightMappingInstruction.weight(), is(equalTo(2)));
+    }
+
+    /**
+     * Tests the equals() method of the MulticastWeightInstruction class.
+     */
+    @Test
+    public void testMulticastWeightInstructionEquals() {
+        checkEqualsAndToString(multiWeight1, sameAsMultiWeight1, multiWeight2);
+    }
+
+    /**
+     * Tests the hashCode() method of the MulticastWeightInstruction class.
+     */
+    @Test
+    public void testMulticastWeightInstructionHashCode() {
+        assertThat(multiWeight1.hashCode(), is(equalTo(sameAsMultiWeight1.hashCode())));
+        assertThat(multiWeight1.hashCode(), is(not(equalTo(multiWeight2.hashCode()))));
+    }
+
+    private final MulticastMappingInstruction multiPriority1 =
+                                    MappingInstructions.multicastPriority(1);
+    private final MulticastMappingInstruction sameAsMultiPriority1 =
+                                    MappingInstructions.multicastPriority(1);
+    private final MulticastMappingInstruction multiPriority2 =
+                                    MappingInstructions.multicastPriority(2);
+
+    /**
+     * Tests the multicastPriority method.
+     */
+    @Test
+    public void testMulticastPriorityMethod() {
+        final MappingInstruction instruction = MappingInstructions.multicastPriority(2);
+        final MulticastMappingInstruction.PriorityMappingInstruction priorityMappingInstruction =
+                checkAndConvert(instruction,
+                                MulticastMappingInstruction.Type.MULTICAST,
+                                MulticastMappingInstruction.PriorityMappingInstruction.class);
+        assertThat(priorityMappingInstruction.priority(), is(equalTo(2)));
+    }
+
+    /**
+     * Tests the equals() method of the MulticastPriorityInstruction class.
+     */
+    @Test
+    public void testMulticastPriorityInstructionEquals() {
+        checkEqualsAndToString(multiPriority1, sameAsMultiPriority1, multiPriority2);
+    }
+
+    /**
+     * Tests the hashCode() method of the MulticastPriorityInstruction class.
+     */
+    @Test
+    public void testMulticastPriorityInstructionHashCode() {
+        assertThat(multiPriority1.hashCode(), is(equalTo(sameAsMultiPriority1.hashCode())));
+        assertThat(multiPriority1.hashCode(), is(not(equalTo(multiPriority2.hashCode()))));
+    }
+
+    // ExtensionMappingInstructionWrapper
+
+    class MockExtensionTreatment implements ExtensionTreatment {
+        int type;
+
+        MockExtensionTreatment(int type) {
+            this.type = type;
+        }
+
+        @Override
+        public ExtensionTreatmentType type() {
+            return new ExtensionTreatmentType(type);
+        }
+
+        @Override
+        public <T> void setPropertyValue(String key, T value) throws ExtensionPropertyException {
+
+        }
+
+        @Override
+        public <T> T getPropertyValue(String key) throws ExtensionPropertyException {
+            return null;
+        }
+
+        @Override
+        public List<String> getProperties() {
+            return null;
+        }
+
+        @Override
+        public byte[] serialize() {
+            return new byte[0];
+        }
+
+        @Override
+        public void deserialize(byte[] data) {
+
+        }
+    }
+
+    private final ExtensionTreatment extensionTreatment1 = new MockExtensionTreatment(111);
+    private final ExtensionTreatment extensionTreatment2 = new MockExtensionTreatment(222);
+
+    private final DeviceId deviceId1 = DeviceId.deviceId("of:1");
+    private final DeviceId deviceId2 = DeviceId.deviceId("of:2");
+
+    private final MappingInstruction extensionInstruction1 =
+            MappingInstructions.extension(extensionTreatment1, deviceId1);
+    private final MappingInstruction sameAsExtensionInstruction1 =
+            MappingInstructions.extension(extensionTreatment1, deviceId1);
+    private final MappingInstruction extensionInstruction2 =
+            MappingInstructions.extension(extensionTreatment2, deviceId2);
+
+    /**
+     * Tests the extension method.
+     */
+    @Test
+    public void testExtensionMethod() {
+        final MappingInstruction instruction =
+                MappingInstructions.extension(extensionTreatment1, deviceId1);
+        final MappingInstructions.ExtensionMappingInstructionWrapper wrapper =
+                checkAndConvert(instruction,
+                                MappingInstruction.Type.EXTENSION,
+                                MappingInstructions.ExtensionMappingInstructionWrapper.class);
+        assertThat(wrapper.deviceId(), is(deviceId1));
+        assertThat(wrapper.extensionMappingInstruction(), is(extensionTreatment1));
+    }
+
+    /**
+     * Tests the equals() method of the ExtensionMappingInstructionWrapper class.
+     */
+    @Test
+    public void testExtensionMappingInstructionWrapperEquals() {
+        checkEqualsAndToString(extensionInstruction1,
+                                sameAsExtensionInstruction1,
+                                extensionInstruction2);
+    }
+
+    /**
+     * Tests the hashCode() method of the ExtensionMappingInstructionWrapper class.
+     */
+    @Test
+    public void testExtensionMappingInstructionWrapperHashCode() {
+        assertThat(extensionInstruction1.hashCode(),
+                            is(equalTo(sameAsExtensionInstruction1.hashCode())));
+        assertThat(extensionInstruction1.hashCode(),
+                            is(not(equalTo(extensionInstruction2.hashCode()))));
+    }
 }
