diff --git a/CMakeLists.txt b/CMakeLists.txt
index ed0a7685307a072ff1f91669a26da84574f57d5f..9c801823ecb179c5c5c37ab0ef274061fa4c8998 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -306,6 +306,8 @@ if (OPENDHT_TESTS)
     list (APPEND test_FILES
       tests/infohashtester.h
       tests/infohashtester.cpp
+      tests/valuetester.h
+      tests/valuetester.cpp
       tests/cryptotester.h
       tests/cryptotester.cpp
       tests/dhtrunnertester.h
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 088dcb6080403512814ddd5c25800c3055c0ff13..252d756554477c9fbe0336764bbe709f646ea320 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -3,7 +3,7 @@ bin_PROGRAMS = opendht_unit_tests
 
 AM_CPPFLAGS = -I../include
 
-nobase_include_HEADERS = infohashtester.h cryptotester.h dhtrunnertester.h dhtproxytester.h
-opendht_unit_tests_SOURCES = tests_runner.cpp cryptotester.cpp infohashtester.cpp dhtrunnertester.cpp dhtproxytester.cpp
+nobase_include_HEADERS = infohashtester.h valuetester.h cryptotester.h dhtrunnertester.h dhtproxytester.h
+opendht_unit_tests_SOURCES = tests_runner.cpp cryptotester.cpp infohashtester.cpp valuetester.cpp dhtrunnertester.cpp dhtproxytester.cpp
 opendht_unit_tests_LDFLAGS = -lopendht -lcppunit -L@top_builddir@/src/.libs @GnuTLS_LIBS@
 endif
diff --git a/tests/infohashtester.cpp b/tests/infohashtester.cpp
index 19b0b85d7c846aea188f96325e35e55d432d8fe9..99a547edf9d9956d666275e8f33c74785c347806 100644
--- a/tests/infohashtester.cpp
+++ b/tests/infohashtester.cpp
@@ -38,14 +38,13 @@ void
 InfoHashTester::testConstructors() {
     // Default constructor creates a null infohash
     auto nullHash = dht::InfoHash();
-    CPPUNIT_ASSERT(nullHash.size() == 20);
+    CPPUNIT_ASSERT_EQUAL((size_t)20u, nullHash.size());
     CPPUNIT_ASSERT(!nullHash);
     // Build from a uint8_t. if length to short, should get a null infohash
     uint8_t to_short[] = {0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8};
     auto infohash = dht::InfoHash(to_short, 8);
-    CPPUNIT_ASSERT(infohash.size() == 20);
-    CPPUNIT_ASSERT_EQUAL(infohash.toString(),
-        std::string("0000000000000000000000000000000000000000"));
+    CPPUNIT_ASSERT_EQUAL((size_t)20u, infohash.size());
+    CPPUNIT_ASSERT_EQUAL(std::string("0000000000000000000000000000000000000000"), infohash.toString());
     // Build from a uint8_t. if length is enough, data should contains the uint8_t
     uint8_t enough[] = {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa,
                         0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa};
@@ -66,7 +65,7 @@ InfoHashTester::testConstructors() {
     }
     // Build from string
     auto infohashFromStr = dht::InfoHash("0102030405060708090A0102030405060708090A");
-    CPPUNIT_ASSERT(infohashFromStr.size() == 20);
+    CPPUNIT_ASSERT_EQUAL((size_t)20u, infohashFromStr.size());
     const auto* dataStr = infohashFromStr.data();
     for (auto i = 0; i < 20; ++i) {
         CPPUNIT_ASSERT_EQUAL((int)dataStr[i], (int)data[i]);
diff --git a/tests/valuetester.cpp b/tests/valuetester.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..0dcf56b95823254053ff7a38dbfd5296cadde7c2
--- /dev/null
+++ b/tests/valuetester.cpp
@@ -0,0 +1,83 @@
+/*
+ *  Copyright (C) 2019 Savoir-faire Linux Inc.
+ *
+ *  Author: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include "valuetester.h"
+
+#include <iostream>
+#include <string>
+
+// opendht
+#include "opendht/value.h"
+
+namespace test {
+CPPUNIT_TEST_SUITE_REGISTRATION(ValueTester);
+
+void
+ValueTester::setUp() {
+
+}
+
+void
+ValueTester::testConstructors() {
+    std::string the_data {"42 cats"};
+    dht::Value the_dht_value {(const uint8_t*)the_data.data(), the_data.size()};
+    std::string from_value {the_dht_value.data.begin(), the_dht_value.data.end()};
+    CPPUNIT_ASSERT_EQUAL(the_data, from_value);
+}
+
+void
+ValueTester::testFilter()
+{
+    dht::Value::Filter defaultFiler {};
+
+    auto isPairSize = dht::Value::Filter([](const dht::Value& v) {
+        return v.data.size() % 2 == 0;
+    });
+
+    auto isUserTypeTest = dht::Value::Filter([](const dht::Value& v) {
+        return v.user_type == "test";
+    });
+
+    std::string data1 {"42 cats"};
+    dht::Value value1 {(const uint8_t*)data1.data(), data1.size()};
+    value1.user_type = "test";
+
+    std::string data2 {"420 cats"};
+    dht::Value value2 {(const uint8_t*)data2.data(), data2.size()};
+    dht::Value value3 {(const uint8_t*)data2.data(), data2.size()};
+    value3.user_type = "test";
+
+    CPPUNIT_ASSERT(!isPairSize(value1));
+    CPPUNIT_ASSERT(isUserTypeTest(value1));
+
+    auto isBoth = dht::Value::Filter::chain(isPairSize, isUserTypeTest);
+    auto isUserTypeTest2 = dht::Value::Filter::chain(defaultFiler, isUserTypeTest);
+
+    CPPUNIT_ASSERT(isUserTypeTest2(value1));
+    CPPUNIT_ASSERT(!isUserTypeTest2(value2));
+    CPPUNIT_ASSERT(!isBoth(value1));
+    CPPUNIT_ASSERT(!isBoth(value2));
+    CPPUNIT_ASSERT(isBoth(value3));
+}
+
+void
+ValueTester::tearDown() {
+
+}
+}  // namespace test
diff --git a/tests/valuetester.h b/tests/valuetester.h
new file mode 100644
index 0000000000000000000000000000000000000000..72dc800c05a7189c4ca3813abe035071c2cff072
--- /dev/null
+++ b/tests/valuetester.h
@@ -0,0 +1,53 @@
+/*
+ *  Copyright (C) 2019 Savoir-faire Linux Inc.
+ *
+ *  Author: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+// cppunit
+#include <cppunit/TestFixture.h>
+#include <cppunit/extensions/HelperMacros.h>
+
+namespace test {
+
+class ValueTester : public CppUnit::TestFixture {
+    CPPUNIT_TEST_SUITE(ValueTester);
+    CPPUNIT_TEST(testConstructors);
+    CPPUNIT_TEST(testFilter);
+    CPPUNIT_TEST_SUITE_END();
+
+ public:
+    /**
+     * Method automatically called before each test by CppUnit
+     */
+    void setUp();
+    /**
+     * Method automatically called after each test CppUnit
+     */
+    void tearDown();
+    /**
+     * Test the differents behaviors of constructors
+     */
+    void testConstructors();
+    /**
+     * Test compare operators
+     */
+    void testFilter();
+};
+
+}  // namespace test