diff --git a/apps/kubevirt-networking/app/src/test/java/org/onosproject/kubevirtnetworking/codec/KubevirtRouterCodecTest.java b/apps/kubevirt-networking/app/src/test/java/org/onosproject/kubevirtnetworking/codec/KubevirtRouterCodecTest.java
new file mode 100644
index 0000000..f2b2470
--- /dev/null
+++ b/apps/kubevirt-networking/app/src/test/java/org/onosproject/kubevirtnetworking/codec/KubevirtRouterCodecTest.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright 2021-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.kubevirtnetworking.codec;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import org.hamcrest.MatcherAssert;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.MacAddress;
+import org.onosproject.codec.JsonCodec;
+import org.onosproject.codec.impl.MockCodecContext;
+import org.onosproject.core.CoreService;
+import org.onosproject.kubevirtnetworking.api.DefaultKubevirtRouter;
+import org.onosproject.kubevirtnetworking.api.KubevirtPeerRouter;
+import org.onosproject.kubevirtnetworking.api.KubevirtRouter;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import static junit.framework.TestCase.assertEquals;
+import static junit.framework.TestCase.assertTrue;
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.onosproject.kubevirtnetworking.codec.KubevirtRouterJsonMatcher.matchesKubevirtRouter;
+import static org.onosproject.net.NetTestTools.APP_ID;
+
+/**
+ * Unit tests for KubevirtRouter codec.
+ */
+public final class KubevirtRouterCodecTest {
+
+    MockCodecContext context;
+
+    JsonCodec<KubevirtRouter> kubevirtRouterCodec;
+
+    final CoreService mockCoreService = createMock(CoreService.class);
+    private static final String REST_APP_ID = "org.onosproject.rest";
+
+    @Before
+    public void setUp() {
+        context = new MockCodecContext();
+        kubevirtRouterCodec = new KubevirtRouterCodec();
+
+        assertThat(kubevirtRouterCodec, notNullValue());
+        expect(mockCoreService.registerApplication(REST_APP_ID))
+                .andReturn(APP_ID).anyTimes();
+        replay(mockCoreService);
+        context.registerService(CoreService.class, mockCoreService);
+    }
+
+    /**
+     * Tests the kubevirt router encoding.
+     */
+    @Test
+    public void testKubevirtRouterEncode() {
+        KubevirtPeerRouter peerRouter = new KubevirtPeerRouter(IpAddress.valueOf("10.10.10.10"),
+                MacAddress.valueOf("11:22:33:44:55:66"));
+
+        KubevirtRouter router = DefaultKubevirtRouter.builder()
+                .name("router-1")
+                .enableSnat(true)
+                .description("router-1")
+                .internal(ImmutableSet.of("vlan-1"))
+                .external(ImmutableMap.of("10.10.10.20", "flat-1"))
+                .peerRouter(peerRouter)
+                .build();
+
+        ObjectNode routerJson = kubevirtRouterCodec.encode(router, context);
+        assertThat(routerJson, matchesKubevirtRouter(router));
+    }
+
+    @Test
+    public void testKubevirtRouterDecode() throws IOException {
+        KubevirtRouter router = getKubevirtRouter("KubevirtRouter.json");
+
+        assertEquals("router-1", router.name());
+        assertEquals("Example Virtual Router", router.description());
+        assertTrue(router.enableSnat());
+        assertEquals("external-network", router.external().get("192.168.10.5"));
+        assertTrue(router.internal().contains("vxlan-network-1"));
+        assertTrue(router.internal().contains("vxlan-network-2"));
+        assertEquals("192.168.10.1", router.peerRouter().ipAddress().toString());
+    }
+
+    private KubevirtRouter getKubevirtRouter(String resourceName) throws IOException {
+        InputStream jsonStream = KubevirtRouterCodecTest.class.getResourceAsStream(resourceName);
+        JsonNode json = context.mapper().readTree(jsonStream);
+        MatcherAssert.assertThat(json, notNullValue());
+        KubevirtRouter router = kubevirtRouterCodec.decode((ObjectNode) json, context);
+        assertThat(router, notNullValue());
+        return router;
+    }
+}
diff --git a/apps/kubevirt-networking/app/src/test/java/org/onosproject/kubevirtnetworking/codec/KubevirtRouterJsonMatcher.java b/apps/kubevirt-networking/app/src/test/java/org/onosproject/kubevirtnetworking/codec/KubevirtRouterJsonMatcher.java
new file mode 100644
index 0000000..1b394e7
--- /dev/null
+++ b/apps/kubevirt-networking/app/src/test/java/org/onosproject/kubevirtnetworking/codec/KubevirtRouterJsonMatcher.java
@@ -0,0 +1,164 @@
+/*
+ * Copyright 2021-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.kubevirtnetworking.codec;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import org.hamcrest.Description;
+import org.hamcrest.TypeSafeDiagnosingMatcher;
+import org.onosproject.kubevirtnetworking.api.KubevirtRouter;
+
+/**
+ * Hamcrest matcher for kubevirt router interface.
+ */
+public final class KubevirtRouterJsonMatcher extends TypeSafeDiagnosingMatcher<JsonNode> {
+
+    private final KubevirtRouter router;
+    private static final String NAME = "name";
+    private static final String DESCRIPTION = "description";
+    private static final String ENABLE_SNAT = "enableSnat";
+    private static final String INTERNAL = "internal";
+    private static final String EXTERNAL = "external";
+    private static final String PEER_ROUTER = "peerRouter";
+    private static final String IP_ADDRESS = "ip";
+    private static final String MAC_ADDRESS = "mac";
+    private static final String NETWORK = "network";
+
+    private KubevirtRouterJsonMatcher(KubevirtRouter router) {
+        this.router = router;
+    }
+
+    @Override
+    protected boolean matchesSafely(JsonNode jsonNode, Description description) {
+
+        // check name
+        String jsonName = jsonNode.get(NAME).asText();
+        String name = router.name();
+        if (!jsonName.equals(name)) {
+            description.appendText("Name was " + jsonName);
+            return false;
+        }
+
+        // check description
+        JsonNode jsonDescription = jsonNode.get(DESCRIPTION);
+        if (jsonDescription != null) {
+            String myDescription = router.description();
+            if (!jsonDescription.asText().equals(myDescription)) {
+                description.appendText("Description was " + jsonDescription);
+                return false;
+            }
+        }
+
+        // check enable snat
+        JsonNode jsonEnableSnat = jsonNode.get(ENABLE_SNAT);
+        if (jsonEnableSnat != null) {
+            boolean enableSnat = router.enableSnat();
+            if (jsonEnableSnat.asBoolean() != enableSnat) {
+                description.appendText("EnableSNAT was " + jsonEnableSnat);
+                return false;
+            }
+        }
+
+        // check internal
+        JsonNode jsonInternal = jsonNode.get(INTERNAL);
+        if (jsonInternal != null) {
+            if (jsonInternal.size() != router.internal().size()) {
+                description.appendText("Internal networks size was " + jsonInternal.size());
+                return false;
+            }
+
+            for (int networkIndex = 0; networkIndex < jsonInternal.size(); networkIndex++) {
+                boolean networkFound = false;
+                String jsonNetwork = jsonInternal.get(networkIndex).asText();
+                if (router.internal().contains(jsonNetwork)) {
+                    networkFound = true;
+                }
+
+                if (!networkFound) {
+                    description.appendText("network not found " + jsonNetwork);
+                    return false;
+                }
+            }
+        }
+
+        // check external
+        ArrayNode jsonExternal = (ArrayNode) jsonNode.get(EXTERNAL);
+        if (jsonExternal != null) {
+            if (jsonExternal.size() != router.external().size()) {
+                description.appendText("External networks size was " + jsonExternal.size());
+                return false;
+            }
+
+            for (int itemIndex = 0; itemIndex < jsonExternal.size(); itemIndex++) {
+                boolean itemFound = false;
+                ObjectNode jsonItem = (ObjectNode) jsonExternal.get(itemIndex);
+                String jsonIp = jsonItem.get(IP_ADDRESS).asText();
+                String jsonNetwork = jsonItem.get(NETWORK).asText();
+
+                if (router.external().containsKey(jsonIp)) {
+                    if (router.external().get(jsonIp).equals(jsonNetwork)) {
+                        itemFound = true;
+                    }
+                }
+
+                if (!itemFound) {
+                    description.appendText("External not found " + jsonItem.toString());
+                    return false;
+                }
+            }
+        }
+
+        // check peer router
+        ObjectNode jsonPeerRouter = (ObjectNode) jsonNode.get(PEER_ROUTER);
+        if (jsonPeerRouter != null) {
+            JsonNode jsonIp = jsonPeerRouter.get(IP_ADDRESS);
+
+            if (jsonIp != null) {
+                if (!jsonIp.asText().equals(router.peerRouter().ipAddress().toString())) {
+                    description.appendText("Peer router IP was " + jsonIp);
+                    return false;
+                }
+            }
+
+            JsonNode jsonMac = jsonPeerRouter.get(MAC_ADDRESS);
+
+            if (jsonMac != null) {
+                if (!jsonMac.asText().equals(router.peerRouter().macAddress().toString())) {
+                    description.appendText("Peer router MAC was " + jsonMac);
+                    return false;
+                }
+            }
+        }
+
+        return true;
+    }
+
+    @Override
+    public void describeTo(Description description) {
+        description.appendText(router.toString());
+    }
+
+    /**
+     * Factory to allocate a kubevirt router matcher.
+     *
+     * @param router kubevirt router object we are looking for
+     * @return matcher
+     */
+    public static KubevirtRouterJsonMatcher matchesKubevirtRouter(KubevirtRouter router) {
+        return new KubevirtRouterJsonMatcher(router);
+    }
+}
