diff --git a/CMakeLists.txt b/CMakeLists.txt
index 764116df0e81f9fe251684963583e03c71b37801..a20f53f8097c68bd8ef2e3592c5bcb906af6412e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -18,6 +18,6 @@ add_executable(ecss_services src/main.cpp src/Message.cpp src/Service.cpp src/Se
 
 IF(EXISTS "${PROJECT_SOURCE_DIR}/lib/Catch2/CMakeLists.txt")
 add_subdirectory(lib/Catch2)
-add_executable(test src/Message.cpp src/Service.cpp src/Services/TestService.cpp tests/tests.cpp tests/Message.cpp)
+add_executable(test src/Message.cpp src/Services/TestService.cpp tests/tests.cpp tests/Message.cpp tests/TestPlatform.cpp tests/Services/TestService.cpp)
 target_link_libraries(test Catch2::Catch2)
 ENDIF()
diff --git a/tests/Services/ServiceTests.hpp b/tests/Services/ServiceTests.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..93c3740c552ac26a684dd0443565492396f66be7
--- /dev/null
+++ b/tests/Services/ServiceTests.hpp
@@ -0,0 +1,53 @@
+#ifndef ECSS_SERVICES_TESTS_SERVICES_SERVICETESTS_HPP
+#define ECSS_SERVICES_TESTS_SERVICES_SERVICETESTS_HPP
+
+#include <vector>
+#include <Message.hpp>
+
+/**
+ * Supporting class for tests against ECSS services
+ *
+ * @todo See if members of this class can be made non-static
+ */
+class ServiceTests {
+	static std::vector<Message> queuedMessages;
+
+public:
+	/**
+	 * Get a message from the list of queued messages to send
+	 * @param number The number of the message, starting from 0 in chronological order
+	 */
+	static Message& get(unsigned long number) {
+		return queuedMessages.at(number);
+	}
+
+	/**
+	 * Add a message to the queue of messages to be sent
+	 */
+	static void queue(const Message &message) {
+		queuedMessages.push_back(message);
+	}
+
+	/**
+	 * Counts the number of messages in the queue
+	 */
+	static unsigned long count() {
+		return queuedMessages.size();
+	}
+
+	/**
+	 * Checks that there is *exactly* one message in the list of queued messages
+	 */
+	static bool hasOneMessage() {
+		return count() == 1;
+	}
+
+	/**
+	 * Remove all the queued messages from the list, starting over from 0 items again
+	 */
+	static void reset() {
+		queuedMessages.clear();
+	}
+};
+
+#endif //ECSS_SERVICES_TESTS_SERVICES_SERVICETESTS_HPP
diff --git a/tests/Services/TestService.cpp b/tests/Services/TestService.cpp
index 139597f9cb07c5d48bed18984ec4747f4b4f3438..0a5233a6dd716b262ce7901f234bc569789852a3 100644
--- a/tests/Services/TestService.cpp
+++ b/tests/Services/TestService.cpp
@@ -1,2 +1,33 @@
+#include <catch2/catch.hpp>
+#include <Services/TestService.hpp>
+#include <Message.hpp>
+#include "ServiceTests.hpp"
 
+TEST_CASE("TM[17,1]", "[service][st17]") {
+	TestService testService;
+
+	Message receivedPacket = Message(17, 1, Message::TC, 1);
+	testService.areYouAlive(receivedPacket);
+	REQUIRE(ServiceTests::hasOneMessage());
+
+	Message response = ServiceTests::get(0);
+	CHECK(response.serviceType == 17);
+	CHECK(response.messageType == 2);
+	REQUIRE(response.dataSize == 0);
+}
+
+TEST_CASE("TM[17,3]", "[service][st17]") {
+	TestService testService;
+
+	Message receivedPacket = Message(17, 3, Message::TC, 1);
+	receivedPacket.appendEnum16(40);
+	testService.onBoardConnection(receivedPacket);
+	REQUIRE(ServiceTests::hasOneMessage());
+
+	Message response = ServiceTests::get(0);
+	CHECK(response.serviceType == 17);
+	CHECK(response.messageType == 4);
+	REQUIRE(response.dataSize == 2);
+	CHECK(response.readEnum16() == 40);
+}
 
diff --git a/tests/TestPlatform.cpp b/tests/TestPlatform.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..08021c0b883fa4409ecb41aba509fd03a4d44c1f
--- /dev/null
+++ b/tests/TestPlatform.cpp
@@ -0,0 +1,26 @@
+#define CATCH_CONFIG_EXTERNAL_INTERFACES
+
+#include <catch2/catch.hpp>
+#include <Message.hpp>
+#include <Service.hpp>
+#include "Services/ServiceTests.hpp"
+
+std::vector<Message> ServiceTests::queuedMessages = std::vector<Message>();
+
+void Service::storeMessage(const Message &message) {
+	ServiceTests::queue(message);
+}
+
+struct ServiceTestsListener : Catch::TestEventListenerBase {
+	using TestEventListenerBase::TestEventListenerBase; // inherit constructor
+
+	void testCaseStarting( Catch::TestCaseInfo const& testInfo ) override {
+		// Perform some setup before a test case is run
+	}
+
+	void testCaseEnded( Catch::TestCaseStats const& testCaseStats ) override {
+		// Tear-down after a test case is run
+		ServiceTests::reset();
+	}
+};
+CATCH_REGISTER_LISTENER( ServiceTestsListener )