diff --git a/src/main/java/net/onrc/onos/apps/sdnip/SdnIp.java b/src/main/java/net/onrc/onos/apps/sdnip/SdnIp.java
index ed7a8ee..ffa9cfa 100644
--- a/src/main/java/net/onrc/onos/apps/sdnip/SdnIp.java
+++ b/src/main/java/net/onrc/onos/apps/sdnip/SdnIp.java
@@ -513,7 +513,7 @@
      *
      * @param update RIB update
      */
-    private void processRibDelete(RibUpdate update) {
+    protected void processRibDelete(RibUpdate update) {
         synchronized (this) {
             Prefix prefix = update.getPrefix();
 
diff --git a/src/test/java/net/onrc/onos/apps/sdnip/RadixTreeTest.java b/src/test/java/net/onrc/onos/apps/sdnip/RadixTreeTest.java
new file mode 100644
index 0000000..1d1034c
--- /dev/null
+++ b/src/test/java/net/onrc/onos/apps/sdnip/RadixTreeTest.java
@@ -0,0 +1,88 @@
+package net.onrc.onos.apps.sdnip;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+import java.net.InetAddress;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.junit.Test;
+
+import com.google.common.net.InetAddresses;
+import com.googlecode.concurrenttrees.radix.node.concrete.DefaultByteArrayNodeFactory;
+import com.googlecode.concurrenttrees.radixinverted.ConcurrentInvertedRadixTree;
+import com.googlecode.concurrenttrees.radixinverted.InvertedRadixTree;
+
+/**
+ * Sanity tests for the InvertedRadixTree.
+ * <p/>
+ * These tests are used to verify that the InvertedRadixTree provides the
+ * functionality we need to fit our use case.
+ */
+public class RadixTreeTest {
+
+    private Map<String, Interface> interfaces;
+    private InvertedRadixTree<Interface> interfaceRoutes;
+
+    private Interface longestInterfacePrefixMatch(InetAddress address) {
+        Prefix prefixToSearchFor = new Prefix(address.getAddress(),
+                Prefix.MAX_PREFIX_LENGTH);
+        Iterator<Interface> it =
+                interfaceRoutes.getValuesForKeysPrefixing(
+                        prefixToSearchFor.toBinaryString()).iterator();
+        Interface intf = null;
+        // Find the last prefix, which will be the longest prefix
+        while (it.hasNext()) {
+            intf = it.next();
+        }
+
+        return intf;
+    }
+
+    /**
+     * This is just a test of the InvertedRadixTree, rather than an actual unit
+     * test of SdnIp. It tests that the algorithm used to retrieve the
+     * longest prefix match from the tree actually does retrieve the longest
+     * prefix, and not just any matching prefix.
+     */
+    @Test
+    public void getOutgoingInterfaceTest() {
+        interfaces = new HashMap<>();
+        interfaceRoutes = new ConcurrentInvertedRadixTree<>(
+                new DefaultByteArrayNodeFactory());
+
+        Interface interface1 = new Interface("sw3-eth1", "00:00:00:00:00:00:00:a3",
+                (short) 1, "192.168.10.101", 24);
+        interfaces.put(interface1.getName(), interface1);
+        Interface interface2 = new Interface("sw5-eth1", "00:00:00:00:00:00:00:a5",
+                (short) 1, "192.168.20.101", 16);
+        interfaces.put(interface2.getName(), interface2);
+        Interface interface3 = new Interface("sw2-eth1", "00:00:00:00:00:00:00:a2",
+                (short) 1, "192.168.60.101", 16);
+        interfaces.put(interface3.getName(), interface3);
+        Interface interface4 = new Interface("sw6-eth1", "00:00:00:00:00:00:00:a6",
+                (short) 1, "192.168.60.101", 30);
+        interfaces.put(interface4.getName(), interface4);
+        Interface interface5 = new Interface("sw4-eth4", "00:00:00:00:00:00:00:a4",
+                (short) 4, "192.168.60.101", 24);
+        interfaces.put(interface5.getName(), interface5);
+
+        for (Interface intf : interfaces.values()) {
+            Prefix prefix = new Prefix(intf.getIpAddress().getAddress(),
+                    intf.getPrefixLength());
+            interfaceRoutes.put(prefix.toBinaryString(), intf);
+        }
+
+        // Check whether the prefix length takes effect
+        InetAddress nextHopAddress = InetAddresses.forString("192.0.0.1");
+        assertNotNull(nextHopAddress);
+        assertNull(longestInterfacePrefixMatch(nextHopAddress));
+
+        // Check whether it returns the longest matchable address
+        nextHopAddress = InetAddresses.forString("192.168.60.101");
+        assertEquals("sw6-eth1", longestInterfacePrefixMatch(nextHopAddress).getName());
+    }
+}
diff --git a/src/test/java/net/onrc/onos/apps/sdnip/SdnIpTest.java b/src/test/java/net/onrc/onos/apps/sdnip/SdnIpTest.java
index f5a6d31..febddca 100644
--- a/src/test/java/net/onrc/onos/apps/sdnip/SdnIpTest.java
+++ b/src/test/java/net/onrc/onos/apps/sdnip/SdnIpTest.java
@@ -1,81 +1,441 @@
 package net.onrc.onos.apps.sdnip;
 
-import static org.junit.Assert.*;
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.expectLastCall;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.reportMatcher;
+import static org.easymock.EasyMock.reset;
+import static org.easymock.EasyMock.verify;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
 
-import java.io.IOException;
 import java.net.InetAddress;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
 import java.util.HashMap;
-import java.util.Iterator;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.List;
 import java.util.Map;
+import java.util.Random;
+import java.util.Set;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
 
+import net.floodlightcontroller.core.module.FloodlightModuleContext;
+import net.floodlightcontroller.core.module.FloodlightModuleException;
+import net.floodlightcontroller.util.MACAddress;
+import net.onrc.onos.api.newintent.IntentId;
+import net.onrc.onos.api.newintent.IntentService;
+import net.onrc.onos.api.newintent.MultiPointToSinglePointIntent;
+import net.onrc.onos.apps.proxyarp.IProxyArpService;
+import net.onrc.onos.apps.sdnip.RibUpdate.Operation;
+import net.onrc.onos.core.matchaction.action.ModifyDstMacAction;
+import net.onrc.onos.core.matchaction.match.PacketMatch;
+import net.onrc.onos.core.matchaction.match.PacketMatchBuilder;
+import net.onrc.onos.core.registry.IControllerRegistryService;
+import net.onrc.onos.core.util.IPv4;
+import net.onrc.onos.core.util.IdBlock;
+import net.onrc.onos.core.util.IntegrationTest;
+import net.onrc.onos.core.util.SwitchPort;
+import net.onrc.onos.core.util.TestUtils;
+
+import org.easymock.IAnswer;
+import org.easymock.IArgumentMatcher;
+import org.junit.Before;
 import org.junit.Test;
+import org.junit.experimental.categories.Category;
 
-import com.googlecode.concurrenttrees.radix.node.concrete.DefaultByteArrayNodeFactory;
-import com.googlecode.concurrenttrees.radixinverted.ConcurrentInvertedRadixTree;
-import com.googlecode.concurrenttrees.radixinverted.InvertedRadixTree;
+import com.google.common.net.InetAddresses;
 
+/**
+ * Integration tests for the SDN-IP application.
+ * <p/>
+ * The tests are very coarse-grained. They feed route updates in to SDN-IP
+ * (simulating routes learnt from BGPd), then they check that the correct
+ * intents are created and submitted to the intent service. The entire route
+ * processing logic of SDN-IP is tested.
+ */
+@Category(IntegrationTest.class)
 public class SdnIpTest {
+    private static final int MAC_ADDRESS_LENGTH = 6;
+    private static final InetAddress ROUTER_ID =
+            InetAddresses.forString("192.168.10.101");
+
+    private static final int MIN_PREFIX_LENGTH = 1;
+    private static final int MAX_PREFIX_LENGTH = 32;
+
+    private SdnIp sdnip;
+    private IProxyArpService proxyArp;
+    private IntentService intentService;
 
     private Map<String, Interface> interfaces;
-    private InvertedRadixTree<Interface> interfaceRoutes;
+    private Map<InetAddress, BgpPeer> peers;
 
-    private Interface longestInterfacePrefixMatch(InetAddress address) {
-        Prefix prefixToSearchFor = new Prefix(address.getAddress(),
-                Prefix.MAX_PREFIX_LENGTH);
-        Iterator<Interface> it =
-                interfaceRoutes.getValuesForKeysPrefixing(
-                        prefixToSearchFor.toBinaryString()).iterator();
-        Interface intf = null;
-        // Find the last prefix, which will be the longest prefix
-        while (it.hasNext()) {
-            intf = it.next();
+    private Random random;
+
+    @Before
+    public void setUp() throws Exception {
+        interfaces = setUpInterfaces();
+        peers = setUpPeers();
+        random = new Random();
+        initSdnIp();
+    }
+
+    private Map<String, Interface> setUpInterfaces() {
+        Map<String, Interface> configuredInterfaces = new HashMap<>();
+
+        String name1 = "s1-eth1";
+        configuredInterfaces.put(name1, new Interface(name1, "00:00:00:00:00:00:00:01",
+                (short) 1, "192.168.10.101", 24));
+        String name2 = "s2-eth1";
+        configuredInterfaces.put(name2, new Interface(name2, "00:00:00:00:00:00:00:02",
+                (short) 1, "192.168.20.101", 24));
+        String name3 = "s3-eth1";
+        configuredInterfaces.put(name3, new Interface(name3, "00:00:00:00:00:00:00:03",
+                (short) 1, "192.168.30.101", 24));
+
+        return configuredInterfaces;
+    }
+
+    private Map<InetAddress, BgpPeer> setUpPeers() {
+        Map<InetAddress, BgpPeer> configuredPeers = new LinkedHashMap<>();
+
+        String peer1 = "192.168.10.1";
+        configuredPeers.put(InetAddresses.forString(peer1),
+                new BgpPeer("s1-eth1", peer1));
+
+        String peer2 = "192.168.20.1";
+        configuredPeers.put(InetAddresses.forString(peer2),
+                new BgpPeer("s2-eth1", peer2));
+
+        String peer3 = "192.168.30.1";
+        configuredPeers.put(InetAddresses.forString(peer3),
+                new BgpPeer("s3-eth1", peer3));
+
+        return configuredPeers;
+    }
+
+    private void initSdnIp() throws FloodlightModuleException {
+        sdnip = new SdnIp();
+
+        FloodlightModuleContext context = new FloodlightModuleContext();
+        context.addConfigParam(sdnip, "BgpdRestIp", "1.1.1.1");
+        context.addConfigParam(sdnip, "RouterId", "192.168.10.101");
+
+        intentService = createMock(IntentService.class);
+        replay(intentService);
+
+        proxyArp = new TestProxyArpService();
+        context.addService(IProxyArpService.class, proxyArp);
+
+        IControllerRegistryService registry =
+                createMock(IControllerRegistryService.class);
+        expect(registry.allocateUniqueIdBlock()).
+                andReturn(new IdBlock(0, Long.MAX_VALUE));
+        replay(registry);
+        context.addService(IControllerRegistryService.class, registry);
+
+        TestUtils.setField(sdnip, "intentService", intentService);
+        sdnip.init(context);
+        TestUtils.setField(sdnip, "interfaces", interfaces);
+        TestUtils.setField(sdnip, "bgpPeers", peers);
+
+    }
+
+    /**
+     * EasyMock matcher that matches {@link MultiPointToSinglePointIntent}s but
+     * ignores the {@link IntentId} when matching.
+     * <p/>
+     * The normal intent equals method tests that the intent IDs are equal,
+     * however in these tests I can't know what the intent IDs will be in
+     * advance, so I can't set up expected intents with the correct IDs. Even
+     * though I can set up an ID generator that generates a sequential stream
+     * of IDs, I don't know in which order the IDs will be assigned to intents
+     * (because intents can be processed out of order due to timing randomness
+     * introduced by the test ARP module).
+     * <p/>
+     * The solution is to use an EasyMock matcher that verifies that all the
+     * value properties of the provided intent match the expected values, but
+     * ignores the intent ID when testing equality.
+     */
+    private static final class IdAgnosticIntentMatcher implements IArgumentMatcher {
+        private final MultiPointToSinglePointIntent intent;
+        private String providedIntentString;
+
+        /**
+         * Constructor taking the expected intent to match against.
+         *
+         * @param intent the expected intent
+         */
+        public IdAgnosticIntentMatcher(MultiPointToSinglePointIntent intent) {
+            this.intent = intent;
         }
 
-        return intf;
+        @Override
+        public void appendTo(StringBuffer strBuffer) {
+            strBuffer.append("IntentMatcher unable to match: " + providedIntentString);
+        }
+
+        @Override
+        public boolean matches(Object object) {
+            if (!(object instanceof MultiPointToSinglePointIntent)) {
+                return false;
+            }
+
+            MultiPointToSinglePointIntent providedIntent =
+                    (MultiPointToSinglePointIntent) object;
+            providedIntentString = providedIntent.toString();
+
+            MultiPointToSinglePointIntent matchIntent =
+                    new MultiPointToSinglePointIntent(providedIntent.getId(),
+                    intent.getMatch(), intent.getAction(), intent.getIngressPorts(),
+                    intent.getEgressPort());
+
+            return matchIntent.equals(providedIntent);
+        }
     }
+
     /**
-     * This is just a test of the InvertedRadixTree, rather than an actual unit
-     * test of SdnIp.
+     * Matcher method to set an expected intent to match against (ignoring the
+     * the intent ID).
      *
-     * @throws IOException
+     * @param intent the expected intent
+     * @return something of type MultiPointToSinglePointIntent
+     */
+    private static MultiPointToSinglePointIntent eqExceptId(
+            MultiPointToSinglePointIntent intent) {
+        reportMatcher(new IdAgnosticIntentMatcher(intent));
+        return null;
+    }
+
+    /**
+     * Tests adding a set of routes into SDN-IP.
+     * <p/>
+     * Random routes are generated and fed in to the SDN-IP route processing
+     * logic (via processRibAdd). We check that the correct intents are
+     * generated and submitted to our mock intent service.
+     *
+     * @throws InterruptedException if interrupted while waiting on a latch
      */
     @Test
-    public void getOutgoingInterfaceTest() throws IOException {
+    public void testAddRoutes() throws InterruptedException {
+        int numRoutes = 100;
 
-        interfaces = new HashMap<>();
-        interfaceRoutes = new ConcurrentInvertedRadixTree<>(
-                new DefaultByteArrayNodeFactory());
+        final CountDownLatch latch = new CountDownLatch(numRoutes);
 
-        Interface interface1 = new Interface("sw3-eth1", "00:00:00:00:00:00:00:a3",
-                (short) 1, "192.168.10.101", 24);
-        interfaces.put(interface1.getName(), interface1);
-        Interface interface2 = new Interface("sw5-eth1", "00:00:00:00:00:00:00:a5",
-                (short) 1, "192.168.20.101", 16);
-        interfaces.put(interface2.getName(), interface2);
-        Interface interface3 = new Interface("sw2-eth1", "00:00:00:00:00:00:00:a2",
-                (short) 1, "192.168.60.101", 16);
-        interfaces.put(interface3.getName(), interface3);
-        Interface interface4 = new Interface("sw6-eth1", "00:00:00:00:00:00:00:a6",
-                (short) 1, "192.168.60.101", 30);
-        interfaces.put(interface4.getName(), interface4);
-        Interface interface5 = new Interface("sw4-eth4", "00:00:00:00:00:00:00:a4",
-                (short) 4, "192.168.60.101", 24);
-        interfaces.put(interface5.getName(), interface5);
+        List<RibUpdate> routeUpdates = generateRouteUpdateIntents(numRoutes);
 
-        for (Interface intf : interfaces.values()) {
-            Prefix prefix = new Prefix(intf.getIpAddress().getAddress(),
-                    intf.getPrefixLength());
-            interfaceRoutes.put(prefix.toBinaryString(), intf);
+        reset(intentService);
+
+        // Set up expectations
+        for (RibUpdate update : routeUpdates) {
+            InetAddress nextHopPeer = update.getRibEntry().getNextHop();
+            MultiPointToSinglePointIntent intent = getIntentForUpdate(update,
+                    generateMacAddress(nextHopPeer),
+                    interfaces.get(peers.get(nextHopPeer).getInterfaceName()));
+            intentService.submit(eqExceptId(intent));
+            expectLastCall().andAnswer(new IAnswer<Object>() {
+                @Override
+                public Object answer() throws Throwable {
+                    latch.countDown();
+                    return null;
+                }
+            }).once();
         }
 
-        // Check whether the prefix length takes effect
-        InetAddress nextHopAddress = InetAddress.getByName("192.0.0.1");
-        assertNotNull(nextHopAddress);
-        assertNull(longestInterfacePrefixMatch(nextHopAddress));
+        replay(intentService);
 
-        // Check whether it returns the longest matchable address
-        nextHopAddress = InetAddress.getByName("192.168.60.101");
-        assertEquals("sw6-eth1", longestInterfacePrefixMatch(nextHopAddress).getName());
+        // Add route updates
+        for (RibUpdate update : routeUpdates) {
+            sdnip.processRibAdd(update);
+        }
 
+        latch.await(5000, TimeUnit.MILLISECONDS);
+
+        assertEquals(sdnip.getPtree().size(), numRoutes);
+
+        verify(intentService);
     }
+
+    /**
+     * Tests adding then deleting a set of routes from SDN-IP.
+     * <p/>
+     * Random routes are generated and fed in to the SDN-IP route processing
+     * logic (via processRibAdd), and we check that the correct intents are
+     * generated. We then delete the entire set of routes (by feeding updates
+     * to processRibDelete), and check that the correct intents are withdrawn
+     * from the intent service.
+     *
+     * @throws InterruptedException if interrupted while waiting on a latch
+     */
+    @Test
+    public void testDeleteRoutes() throws InterruptedException {
+        int numRoutes = 100;
+        List<RibUpdate> routeUpdates = generateRouteUpdateIntents(numRoutes);
+
+        final CountDownLatch installCount = new CountDownLatch(numRoutes);
+        final CountDownLatch deleteCount = new CountDownLatch(numRoutes);
+
+        reset(intentService);
+
+        for (RibUpdate update : routeUpdates) {
+            InetAddress nextHopPeer = update.getRibEntry().getNextHop();
+            MultiPointToSinglePointIntent intent = getIntentForUpdate(update,
+                    generateMacAddress(nextHopPeer),
+                    interfaces.get(peers.get(nextHopPeer).getInterfaceName()));
+            intentService.submit(eqExceptId(intent));
+            expectLastCall().andAnswer(new IAnswer<Object>() {
+                @Override
+                public Object answer() throws Throwable {
+                    installCount.countDown();
+                    return null;
+                }
+            }).once();
+            intentService.withdraw(eqExceptId(intent));
+            expectLastCall().andAnswer(new IAnswer<Object>() {
+                @Override
+                public Object answer() throws Throwable {
+                    deleteCount.countDown();
+                    return null;
+                }
+            }).once();
+        }
+
+        replay(intentService);
+
+
+        // Send the add updates first
+        for (RibUpdate update : routeUpdates) {
+            sdnip.processRibAdd(update);
+        }
+
+        // Give some time to let the intents be submitted
+        installCount.await(5000, TimeUnit.MILLISECONDS);
+
+        // Send the DELETE updates
+        for (RibUpdate update : routeUpdates) {
+            RibUpdate deleteUpdate = new RibUpdate(Operation.DELETE,
+                    update.getPrefix(), update.getRibEntry());
+            sdnip.processRibDelete(deleteUpdate);
+        }
+
+        deleteCount.await(5000, TimeUnit.MILLISECONDS);
+
+        assertEquals(0, sdnip.getPtree().size());
+
+        verify(intentService);
+    }
+
+    /**
+     * Generates a set of route updates. The prefix for each route is randomly
+     * generated, and the next hop is selected from the set of BGP peers that
+     * was generated during {@link #setUp()}. All have the UPDATE operation.
+     * The generated prefixes are unique within the batch generated by each
+     * call of this method.
+     *
+     * @param numRoutes the number of route updates to generate
+     * @return a list of generated route updates
+     */
+    private List<RibUpdate> generateRouteUpdateIntents(int numRoutes) {
+        List<RibUpdate> routeUpdates = new ArrayList<>(numRoutes);
+
+        Set<Prefix> prefixes = new HashSet<>();
+
+        for (int i = 0; i < numRoutes; i++) {
+            Prefix prefix;
+            do {
+                InetAddress prefixAddress = InetAddresses.fromInteger(random.nextInt());
+                // Generate a random prefix length between MIN_PREFIX_LENGTH and
+                // MAX_PREFIX_LENGTH
+                int prefixLength = random.nextInt(
+                        (MAX_PREFIX_LENGTH - MIN_PREFIX_LENGTH) + 1) + MIN_PREFIX_LENGTH;
+                prefix = new Prefix(prefixAddress.getAddress(), prefixLength);
+                // We have to ensure we don't generate the same prefix twice
+                // (this is quite easy to do with small prefix lengths)
+            } while (prefixes.contains(prefix));
+
+            prefixes.add(prefix);
+
+            // Randomly select a peer to use as the next hop
+            BgpPeer nextHop = null;
+            int peerNumber = random.nextInt(peers.size());
+            int j = 0;
+            for (BgpPeer peer : peers.values()) {
+                if (j++ == peerNumber) {
+                    nextHop = peer;
+                    break;
+                }
+            }
+
+            assertNotNull(nextHop);
+
+            RibUpdate update = new RibUpdate(Operation.UPDATE, prefix,
+                    new RibEntry(ROUTER_ID, nextHop.getIpAddress()));
+
+            routeUpdates.add(update);
+        }
+
+        return routeUpdates;
+    }
+
+    /**
+     * Generates the MultiPointToSinglePointIntent that should be
+     * submitted/withdrawn for a particular RibUpdate.
+     *
+     * @param update the RibUpdate to generate an intent for
+     * @param nextHopMac a MAC address to use as the dst-mac for the intent
+     * @param egressInterface the outgoing interface for the intent
+     * @return the generated intent
+     */
+    private MultiPointToSinglePointIntent getIntentForUpdate(RibUpdate update,
+            MACAddress nextHopMac, Interface egressInterface) {
+        Prefix prefix = update.getPrefix();
+
+        PacketMatchBuilder builder = new PacketMatchBuilder();
+        builder.setDstIp(new IPv4(
+                InetAddresses.coerceToInteger(prefix.getInetAddress())),
+                (short) prefix.getPrefixLength());
+        PacketMatch match = builder.build();
+
+        ModifyDstMacAction action = new ModifyDstMacAction(nextHopMac);
+
+        Set<SwitchPort> ingressPorts = new HashSet<>();
+        for (Interface intf : interfaces.values()) {
+            if (!intf.equals(egressInterface)) {
+                ingressPorts.add(intf.getSwitchPort());
+            }
+        }
+
+        // Create the intent. The intent ID is arbitrary because we don't consider
+        // it when matching against the intent passed to the mock
+        MultiPointToSinglePointIntent intent = new MultiPointToSinglePointIntent(
+                new IntentId(0), match, action, ingressPorts,
+                egressInterface.getSwitchPort());
+
+        return intent;
+    }
+
+    /**
+     * Generates a MAC address based on an IP address.
+     * For the test we need MAC addresses but the actual values don't have any
+     * meaning, so we'll just generate them based on the IP address. This means
+     * we have a deterministic mapping from IP address to MAC address.
+     *
+     * @param ipAddress IP address used to generate a MAC address
+     * @return generated MAC address
+     */
+    public static MACAddress generateMacAddress(InetAddress ipAddress) {
+        byte[] macAddress = new byte[MAC_ADDRESS_LENGTH];
+        ByteBuffer bb = ByteBuffer.wrap(macAddress);
+
+        // Put the IP address bytes into the lower four bytes of the MAC address.
+        // Leave the first two bytes set to 0.
+        bb.position(2);
+        bb.put(ipAddress.getAddress());
+
+        return MACAddress.valueOf(bb.array());
+    }
+
 }
diff --git a/src/test/java/net/onrc/onos/apps/sdnip/TestProxyArpService.java b/src/test/java/net/onrc/onos/apps/sdnip/TestProxyArpService.java
new file mode 100644
index 0000000..d6129ac
--- /dev/null
+++ b/src/test/java/net/onrc/onos/apps/sdnip/TestProxyArpService.java
@@ -0,0 +1,108 @@
+package net.onrc.onos.apps.sdnip;
+
+import java.net.InetAddress;
+import java.util.List;
+import java.util.Random;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+import net.floodlightcontroller.util.MACAddress;
+import net.onrc.onos.apps.proxyarp.IArpRequester;
+import net.onrc.onos.apps.proxyarp.IProxyArpService;
+
+/**
+ * Test version of the IProxyArpService which is used to simulate delays in
+ * receiving ARP replies, as you would see in a real system due to the time
+ * it takes to proxy ARP packets to/from the host. Requests are asynchronous,
+ * and replies may come back to the requestor in a different order than the
+ * requests were sent, which again you would expect to see in a real system.
+ */
+public class TestProxyArpService implements IProxyArpService {
+
+    /**
+     * The maximum possible delay before an ARP reply is received.
+     */
+    private static final int MAX_ARP_REPLY_DELAY = 30; // milliseconds
+
+    /**
+     * The probability that we already have the MAC address cached when the
+     * caller calls {@link #getMacAddress(InetAddress)}.
+     */
+    private static final float MAC_ALREADY_KNOWN_PROBABILITY = 0.3f;
+
+    private final ScheduledExecutorService replyTaskExecutor;
+
+    private final Random random;
+
+    /**
+     * Class constructor.
+     */
+    public TestProxyArpService() {
+        replyTaskExecutor = Executors.newSingleThreadScheduledExecutor();
+        random = new Random();
+    }
+
+    /**
+     * Task used to reply to ARP requests from a different thread. Replies
+     * usually come on a different thread in the real system, so we need to
+     * ensure we test this behaviour.
+     */
+    private static class ReplyTask implements Runnable {
+        private IArpRequester requestor;
+        private InetAddress ipAddress;
+        private MACAddress macAddress;
+
+        /**
+         * Class constructor.
+         *
+         * @param requestor the client who requested the MAC address
+         * @param ipAddress the target IP address of the request
+         * @param macAddress the MAC address in the ARP reply
+         */
+        public ReplyTask(IArpRequester requestor, InetAddress ipAddress,
+                MACAddress macAddress) {
+            this.requestor = requestor;
+            this.ipAddress = ipAddress;
+            this.macAddress = macAddress;
+        }
+
+        @Override
+        public void run() {
+            requestor.arpResponse(ipAddress, macAddress);
+        }
+    }
+
+    @Override
+    public MACAddress getMacAddress(InetAddress ipAddress) {
+        float replyChance = random.nextFloat();
+        if (replyChance < MAC_ALREADY_KNOWN_PROBABILITY) {
+            // Some percentage of the time we already know the MAC address, so
+            // we reply directly when the requestor asks for the MAC address
+            return SdnIpTest.generateMacAddress(ipAddress);
+        }
+        return null;
+    }
+
+    @Override
+    public void sendArpRequest(InetAddress ipAddress, IArpRequester requester,
+            boolean retry) {
+        // Randomly select an amount of time to delay the reply coming back to
+        // the requestor (simulating time taken to proxy the request to a
+        // network host).
+        int delay = random.nextInt(MAX_ARP_REPLY_DELAY);
+
+        MACAddress macAddress = SdnIpTest.generateMacAddress(ipAddress);
+
+        ReplyTask replyTask = new ReplyTask(requester, ipAddress, macAddress);
+
+        replyTaskExecutor.schedule(replyTask , delay, TimeUnit.MILLISECONDS);
+    }
+
+    @Override
+    public List<String> getMappings() {
+        // We don't care about this method for the current test use cases
+        return null;
+    }
+
+}
