diff --git a/src/gpu/VirtualFluids_GPU/Factories/BoundaryConditionFactory.h b/src/gpu/VirtualFluids_GPU/Factories/BoundaryConditionFactory.h
index c6877cbfeffe5b32c0c2d336e46b02d68cd946a3..09f1a44166829f73c79cd839a7ecf75deae0e67e 100644
--- a/src/gpu/VirtualFluids_GPU/Factories/BoundaryConditionFactory.h
+++ b/src/gpu/VirtualFluids_GPU/Factories/BoundaryConditionFactory.h
@@ -161,15 +161,14 @@ public:
     // void setOutflowBoundaryCondition(...); // TODO:
     // https://git.rz.tu-bs.de/m.schoenherr/VirtualFluids_dev/-/issues/16
 
-    [[nodiscard]] boundaryCondition getVelocityBoundaryConditionPost(bool isGeometryBC = false) const;
+    [[nodiscard]] virtual boundaryCondition getVelocityBoundaryConditionPost(bool isGeometryBC = false) const;
     [[nodiscard]] boundaryCondition getNoSlipBoundaryConditionPost(bool isGeometryBC = false) const;
     [[nodiscard]] boundaryCondition getSlipBoundaryConditionPost(bool isGeometryBC = false) const;
     [[nodiscard]] boundaryCondition getPressureBoundaryConditionPre() const;
     [[nodiscard]] boundaryCondition getGeometryBoundaryConditionPost() const;
-    [[nodiscard]] precursorBoundaryConditionFunc getPrecursorBoundaryConditionPost() const;
-
 
     [[nodiscard]] boundaryConditionWithParameter getStressBoundaryConditionPost() const;
+    [[nodiscard]] precursorBoundaryConditionFunc getPrecursorBoundaryConditionPost() const;
 
 private:
     VelocityBC velocityBoundaryCondition = VelocityBC::NotSpecified;
diff --git a/src/gpu/VirtualFluids_GPU/Factories/BoundaryConditionFactoryTest.cpp b/src/gpu/VirtualFluids_GPU/Factories/BoundaryConditionFactoryTest.cpp
index 14d01d6df3334d767d97e8db87b7e2a9964022e3..a01b6af7abfebcdf488a66fc0c0ba1c9d3c81987 100644
--- a/src/gpu/VirtualFluids_GPU/Factories/BoundaryConditionFactoryTest.cpp
+++ b/src/gpu/VirtualFluids_GPU/Factories/BoundaryConditionFactoryTest.cpp
@@ -55,6 +55,8 @@ TEST(BoundaryConditionFactoryTest, defaultStressBC)
     EXPECT_THROW(bc(nullptr, nullptr, 0), std::bad_function_call);
 }
 
+// tests for boundary conditions which are set by the user (tests both set and get functions)
+
 bcFunction getVelocityBcTarget(BoundaryConditionFactory &bcFactory)
 {
     auto bc = bcFactory.getVelocityBoundaryConditionPost();
@@ -63,8 +65,6 @@ bcFunction getVelocityBcTarget(BoundaryConditionFactory &bcFactory)
     return bcTarget;
 }
 
-// tests for boundary conditions whcih are set by the user (tests both set and get functions)
-
 TEST(BoundaryConditionFactoryTest, velocityBC)
 {
     auto bcFactory = BoundaryConditionFactory();
diff --git a/src/gpu/VirtualFluids_GPU/KernelManager/BCKernelManagerTest.cpp b/src/gpu/VirtualFluids_GPU/KernelManager/BCKernelManagerTest.cpp
index a0e02112e821eedcfeb013d3465529f668309529..6b429d2d9c03e546286d3d2b0ced3612c0a4649a 100644
--- a/src/gpu/VirtualFluids_GPU/KernelManager/BCKernelManagerTest.cpp
+++ b/src/gpu/VirtualFluids_GPU/KernelManager/BCKernelManagerTest.cpp
@@ -1,3 +1,4 @@
+
 #include <gmock/gmock.h>
 #include <stdexcept>
 
@@ -18,44 +19,123 @@ protected:
     }
 };
 
-TEST_F(BCKernelManagerTest_BCsNotSpecified, velocityBoundaryConditionPost_NotSpecified)
+TEST_F(BCKernelManagerTest_BCsNotSpecified, velocityBoundaryConditionPostNotSpecified_noBoundaryNodes_doesNotThrow)
+{
+    para->getParD(0)->velocityBC.numberOfBCnodes = 0;
+    EXPECT_NO_THROW(BCKernelManager(para, &bcFactory));
+}
+
+TEST_F(BCKernelManagerTest_BCsNotSpecified, velocityBoundaryConditionPostNotSpecified_withBoundaryNodes_throws)
 {
     para->getParD(0)->velocityBC.numberOfBCnodes = 1;
     EXPECT_THROW(BCKernelManager(para, &bcFactory), std::runtime_error);
 }
 
-TEST_F(BCKernelManagerTest_BCsNotSpecified, noSlipBoundaryConditionPost_NotSpecified)
+TEST_F(BCKernelManagerTest_BCsNotSpecified, noSlipBoundaryConditionPostNotSpecified_noBoundaryNodes_doesNotThrow)
+{
+    para->getParD(0)->noSlipBC.numberOfBCnodes = 0;
+    EXPECT_NO_THROW(BCKernelManager(para, &bcFactory));
+}
+
+TEST_F(BCKernelManagerTest_BCsNotSpecified, noSlipBoundaryConditionPostNotSpecified_withBoundaryNodes_doesNotThrow)
 {
     para->getParD(0)->noSlipBC.numberOfBCnodes = 1;
     EXPECT_NO_THROW(BCKernelManager(para, &bcFactory)); // no throw, as a default is specified
 }
 
-TEST_F(BCKernelManagerTest_BCsNotSpecified, slipBoundaryConditionPost_NotSpecified)
+TEST_F(BCKernelManagerTest_BCsNotSpecified, slipBoundaryConditionPostNotSpecified_noBoundaryNodes_doesNotThrow)
+{
+    para->getParD(0)->slipBC.numberOfBCnodes = 0;
+    EXPECT_NO_THROW(BCKernelManager(para, &bcFactory));
+}
+
+TEST_F(BCKernelManagerTest_BCsNotSpecified, slipBoundaryConditionPostNotSpecified_withBoundaryNodes_throws)
 {
     para->getParD(0)->slipBC.numberOfBCnodes = 1;
     EXPECT_THROW(BCKernelManager(para, &bcFactory), std::runtime_error);
 }
 
-TEST_F(BCKernelManagerTest_BCsNotSpecified, pressureBoundaryConditionPre_NotSpecified)
+TEST_F(BCKernelManagerTest_BCsNotSpecified, pressureBoundaryConditionPreNotSpecified_noBoundaryNodes_doesNotThrow)
+{
+    para->getParD(0)->pressureBC.numberOfBCnodes = 0;
+    EXPECT_NO_THROW(BCKernelManager(para, &bcFactory));
+}
+
+TEST_F(BCKernelManagerTest_BCsNotSpecified, pressureBoundaryConditionPreNotSpecified_withBoundaryNodes_throws)
 {
     para->getParD(0)->pressureBC.numberOfBCnodes = 1;
     EXPECT_THROW(BCKernelManager(para, &bcFactory), std::runtime_error);
 }
 
-TEST_F(BCKernelManagerTest_BCsNotSpecified, geometryBoundaryConditionPost_NotSpecified)
+TEST_F(BCKernelManagerTest_BCsNotSpecified, geometryBoundaryConditionPostNotSpecified_noBoundaryNodes_doesNotThrow)
+{
+    para->getParD(0)->geometryBC.numberOfBCnodes = 0;
+    EXPECT_NO_THROW(BCKernelManager(para, &bcFactory));
+}
+
+TEST_F(BCKernelManagerTest_BCsNotSpecified, geometryBoundaryConditionPostNotSpecified_withBoundaryNodes_doesNotThrow)
 {
     para->getParD(0)->geometryBC.numberOfBCnodes = 1;
     EXPECT_NO_THROW(BCKernelManager(para, &bcFactory)); // no throw, as a default is specified
 }
 
-TEST_F(BCKernelManagerTest_BCsNotSpecified, stressBoundaryConditionPost_NotSpecified)
+TEST_F(BCKernelManagerTest_BCsNotSpecified, stressBoundaryConditionPostNotSpecified_noBoundaryNodes_doesNotThrow)
+{
+    para->getParD(0)->stressBC.numberOfBCnodes = 0;
+    EXPECT_NO_THROW(BCKernelManager(para, &bcFactory));
+}
+
+TEST_F(BCKernelManagerTest_BCsNotSpecified, stressBoundaryConditionPostNotSpecified_withBoundaryNodes_throws)
 {
     para->getParD(0)->stressBC.numberOfBCnodes = 1;
     EXPECT_THROW(BCKernelManager(para, &bcFactory), std::runtime_error);
 }
 
-TEST_F(BCKernelManagerTest_BCsNotSpecified, precursorBoundaryConditionPost_NotSpecified)
+TEST_F(BCKernelManagerTest_BCsNotSpecified, precursorBoundaryConditionPostNotSpecified_noBoundaryNodes_doesNotThrow)
+{
+    para->getParD(0)->precursorBC.numberOfBCnodes = 0;
+    EXPECT_NO_THROW(BCKernelManager(para, &bcFactory));
+}
+
+TEST_F(BCKernelManagerTest_BCsNotSpecified, precursorBoundaryConditionPostNotSpecified_withBoundaryNodes_throws)
 {
     para->getParD(0)->precursorBC.numberOfBCnodes = 1;
     EXPECT_THROW(BCKernelManager(para, &bcFactory), std::runtime_error);
 }
+
+class BoundaryConditionFactoryMock : public BoundaryConditionFactory
+{
+public:
+    mutable uint numberOfCalls = 0;
+
+    [[nodiscard]] boundaryCondition getVelocityBoundaryConditionPost(bool) const override
+    {
+        return [this](LBMSimulationParameter *, QforBoundaryConditions *) { numberOfCalls++; };
+    }
+};
+
+class BCKernelManagerTest_runBCs : public testing::Test
+{
+protected:
+    BoundaryConditionFactoryMock bcFactory;
+    SPtr<Parameter> para = std::make_shared<Parameter>();
+    UPtr<BCKernelManager> sut;
+
+    void SetUp() override
+    {
+        para->initLBMSimulationParameter();
+        sut = std::make_unique<BCKernelManager>(para, &bcFactory);
+    }
+};
+
+TEST_F(BCKernelManagerTest_runBCs, runVelocityBCKernelPost)
+{
+    para->getParD(0)->velocityBC.numberOfBCnodes = 1;
+    sut->runVelocityBCKernelPost(0);
+    EXPECT_THAT(bcFactory.numberOfCalls, testing::Eq(1));
+
+    bcFactory.numberOfCalls = 0;
+    para->getParD(0)->velocityBC.numberOfBCnodes = 0;
+    sut->runVelocityBCKernelPost(0);
+    EXPECT_THAT(bcFactory.numberOfCalls, testing::Eq(0));
+}
diff --git a/src/gpu/VirtualFluids_GPU/KernelManager/GridScalingKernelManagerTest.cpp b/src/gpu/VirtualFluids_GPU/KernelManager/GridScalingKernelManagerTest.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..b86e167ca8d2f95897b1a87d4b850acbfbe8a1b3
--- /dev/null
+++ b/src/gpu/VirtualFluids_GPU/KernelManager/GridScalingKernelManagerTest.cpp
@@ -0,0 +1,81 @@
+#include <gmock/gmock.h>
+#include <stdexcept>
+
+#include "GridScalingKernelManager.h"
+#include "Factories/GridScalingFactory.h"
+#include "Parameter/Parameter.h"
+#include "PointerDefinitions.h"
+
+class GridScalingKernelManagerTest_Initialization : public testing::Test
+{
+protected:
+    GridScalingFactory scalingFactory;
+    SPtr<Parameter> para = std::make_shared<Parameter>();
+
+    void SetUp() override
+    {
+        para->setGridX({2, 8});
+        para->setGridY({2, 8});
+        para->setGridZ({2, 8});
+        para->setDistX({0, 0});
+        para->setDistY({0, 0});
+        para->setDistZ({0, 0});
+    }
+};
+
+TEST_F(GridScalingKernelManagerTest_Initialization, singleLevel_noScalingFactoryProvided_doesNotThrow)
+{
+    // only one level --> no scaling factory needed --> no error
+    para->initLBMSimulationParameter();
+    EXPECT_NO_THROW(GridScalingKernelManager(para, nullptr));
+}
+
+TEST_F(GridScalingKernelManagerTest_Initialization, singleLevel_scalingFactoryProvided_doesNotThrow)
+{
+    // only one level --> no scaling function needed --> no error
+    para->initLBMSimulationParameter();
+    EXPECT_NO_THROW(GridScalingKernelManager(para, &scalingFactory));
+}
+
+TEST_F(GridScalingKernelManagerTest_Initialization, singleLevel_scalingFactoryAndFunctionProvided_doesNotThrow)
+{
+    // only one level, but the user provided a scaling function anyway --> no error
+    para->initLBMSimulationParameter();
+    scalingFactory.setScalingFactory(GridScalingFactory::GridScaling::ScaleCompressible);
+    EXPECT_NO_THROW(GridScalingKernelManager(para, &scalingFactory));
+}
+
+TEST_F(GridScalingKernelManagerTest_Initialization, multipleLevels_notScalingFactoryProvided_throws)
+{
+    // multiple levels, but the user forgot the scaling factory --> error
+    para->setMaxLevel(2);
+    para->initLBMSimulationParameter();
+    EXPECT_THROW(GridScalingKernelManager(para, nullptr), std::runtime_error);
+}
+
+TEST_F(GridScalingKernelManagerTest_Initialization, multipleLevelWithoutInterpolationNodes_noScalingFunctionProvided_doesNotThrow)
+{
+    // multiple levels, but no interpolation nodes specified --> no scaling function needed --> no error
+    para->setMaxLevel(2);
+    para->initLBMSimulationParameter();
+    EXPECT_NO_THROW(GridScalingKernelManager(para, &scalingFactory));
+}
+
+TEST_F(GridScalingKernelManagerTest_Initialization, multipleLevelWithoutInterpolationNodes_scalingFunctionProvided_doesNotThrow)
+{
+    // multiple levels and NO interpolation nodes specified, but the user provided a scaling function anyway --> no error
+    para->setMaxLevel(2);
+    para->initLBMSimulationParameter();
+    scalingFactory.setScalingFactory(GridScalingFactory::GridScaling::ScaleRhoSq);
+    EXPECT_NO_THROW(GridScalingKernelManager(para, &scalingFactory));
+}
+
+TEST_F(GridScalingKernelManagerTest_Initialization, multipleLevelWithInterpolationNodes_noScalingFunctionProvided_throws)
+{
+    // multiple levels and interpolation nodes specified, but the user forgot to set the scalingFunction --> error
+    para->setMaxLevel(2);
+    para->initLBMSimulationParameter();
+    para->getParD(0)->fineToCoarse.numberOfCells = 100;
+    EXPECT_THROW(GridScalingKernelManager(para, &scalingFactory), std::runtime_error);
+}
+