diff --git a/source/general/game_state/shoe.cpp b/source/general/game_state/shoe.cpp
index c43a6c6d6c14373973424c78e03a89d3c0528e9b..def68de2bd1820d64c91f09b090d86ab176ed69a 100644
--- a/source/general/game_state/shoe.cpp
+++ b/source/general/game_state/shoe.cpp
@@ -32,10 +32,6 @@ void shoe::shuffle() {
     std::shuffle(_cards.begin(), _cards.end(), std::mt19937(std::random_device()()));
 }
 
-bool shoe::is_empty() const noexcept  {
-    return _cards.empty();
-}
-
 void shoe::setup_round(std::string &err) {
     // remove all cards
     for (int i = 0; i < _cards.size(); i++) {
diff --git a/source/general/game_state/shoe.hpp b/source/general/game_state/shoe.hpp
index 975589e882ca5cf491b8ee1c68875956a892fb4a..2b400591a78a7480cfb8e50d79413e0cfd3de894 100644
--- a/source/general/game_state/shoe.hpp
+++ b/source/general/game_state/shoe.hpp
@@ -32,13 +32,15 @@ public:
 
     // pile functions
     void shuffle();
-    bool is_empty() const noexcept;
     void setup_round(std::string &err);
     card* draw_card(hand* h, std::string& err);
 
     // serialization
     virtual void write_into_json(rapidjson::Value& json, rapidjson::Document::AllocatorType& allocator) const override;
     static shoe* from_json(const rapidjson::Value& json);
+
+    //friend function used for testing
+    friend std::vector<card*> get_cards(const shoe& shoe);
 };
 
 
diff --git a/unit-tests/hand.cpp b/unit-tests/hand.cpp
index d65a54e9cf1a9cda90cbd6f7cbfb58c51f01e12f..72d9e9ed6d2d017f2902a5c20372ecbedcf3f66d 100644
--- a/unit-tests/hand.cpp
+++ b/unit-tests/hand.cpp
@@ -2,9 +2,6 @@
 // Created by Flavia Taras on 20.05.22.
 //
 
-//TODO try to get extra cards when you already have over 21 points
-//TODO: adding the same card more than the number of decks in a shoe should not work
-
 #include "gtest/gtest.h"
 #include "../source/general/game_state/hand.hpp"
 #include "../source/general/exceptions/BlackjackException.hpp"
diff --git a/unit-tests/shoe.cpp b/unit-tests/shoe.cpp
index 6dfad54aa7c2d5eaa9f3a527cb54617d12c8bcd0..146f3fa0bbb7d15c9ee3dd2ec7e28e33f1d30e2b 100644
--- a/unit-tests/shoe.cpp
+++ b/unit-tests/shoe.cpp
@@ -2,3 +2,53 @@
 // Created by Flavia Taras on 24.05.22.
 //
 
+#include "gtest/gtest.h"
+#include "../source/general/game_state/shoe.hpp"
+#include "../source/general/exceptions/BlackjackException.hpp"
+#include "../source/general/serialization/json_utils.h"
+
+std::vector<card*> get_cards(const shoe& shoe) {
+    return shoe._cards;
+}
+
+class ShoeTest : public ::testing::Test {
+
+protected:
+    virtual void SetUp() {
+        cards.resize(224);
+        for (int i = 0; i < 4; ++i) { //number of decks in a shoe
+            for (int j = 1; j < 14; ++j) { //card values
+                for (int k = 0; k < 4; ++k) { //card suits
+                    cards.push_back(new card(j, k));
+                }
+            }
+        }
+
+    }
+
+    /* Any object and subroutine declared here can be accessed in the tests */
+    shoe shoe_;
+    std::vector<card*> cards;
+    std::string err;
+};
+
+
+// Serialization and subsequent deserialization must yield the same object
+TEST_F(ShoeTest, SerializationEquality) {
+    rapidjson::Document* json_send = shoe_.to_json();
+    std::string message = json_utils::to_string(json_send);
+    delete json_send;
+
+    rapidjson::Document json_received = rapidjson::Document(rapidjson::kObjectType);
+    json_received.Parse(message.c_str());
+    shoe* shoe_received = shoe::from_json(json_received);
+    EXPECT_EQ(get_cards(shoe_), get_cards(*shoe_received));
+    delete shoe_received;
+}
+
+// Deserializing an invalid string must throw a BlackjackException
+TEST_F(ShoeTest, SerializationException) {
+    rapidjson::Document json = rapidjson::Document(rapidjson::kObjectType);
+    json.Parse("not json");
+    EXPECT_THROW(shoe::from_json(json), BlackjackException);
+}
\ No newline at end of file