diff --git a/dune/fufem/test/CMakeLists.txt b/dune/fufem/test/CMakeLists.txt
index f27a906f449bc2ba1cfb37cd8a45ff0282b81096..3ca8e185dfd915af31db580a77082dcfd6727790 100644
--- a/dune/fufem/test/CMakeLists.txt
+++ b/dune/fufem/test/CMakeLists.txt
@@ -24,6 +24,7 @@ set(GRID_BASED_TESTS
   subgridxyfunctionalassemblertest
   sumfunctiontest
   tensortest
+  transferoperatorassemblertest
   )
 
 if (ADOLC_FOUND)
diff --git a/dune/fufem/test/transferoperatorassemblertest.cc b/dune/fufem/test/transferoperatorassemblertest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..dd97c8265d8d70870865be90649e599496da6d69
--- /dev/null
+++ b/dune/fufem/test/transferoperatorassemblertest.cc
@@ -0,0 +1,121 @@
+#include <config.h>
+
+#include <dune/common/parallel/mpihelper.hh>
+#include <dune/common/parametertree.hh>
+#include <dune/common/fmatrix.hh>
+
+#include <dune/istl/bcrsmatrix.hh>
+
+#include <dune/alugrid/grid.hh>
+#include <dune/grid/uggrid.hh>
+#if HAVE_DUNE_SUBGRID
+#include <dune/subgrid/subgrid.hh>
+#endif
+
+#include <dune/fufem/assemblers/transferoperatorassembler.hh>
+#include <dune/fufem/utilities/gridconstruction.hh>
+
+using namespace Dune;
+
+constexpr size_t level = 3;
+
+template <class Grid, size_t D>
+auto createGrid() {
+  ParameterTree config;
+  if (D == 2) {
+    config["type"] = "rectangle";
+    config["lowerCorner"] = "0.0 0.0";
+    config["upperCorner"] = "1.0 1.0";
+    config["elements"] = "1 1";
+    config["tetrahedral"] = "1";
+  } else
+    DUNE_THROW(NotImplemented, "No grid config available for this dim.");
+
+  auto grid = GridConstruction<Grid, D>::createGrid(config);
+
+  for (size_t r = 0; r < level; ++r)
+    grid->globalRefine(1);
+
+  return grid;
+}
+
+template <class Grid, size_t D>
+bool test(const Grid& grid) {
+  using TOA = TransferOperatorAssembler<Grid>;
+  using Matrix = BCRSMatrix<FieldMatrix<double, 1, 1>>;
+  using Hierarchy = std::vector<std::shared_ptr<Matrix>>;
+  Hierarchy hierarchy;
+  TOA toa(grid);
+  toa.assembleMatrixHierarchy(hierarchy);
+
+  for (size_t i = 0; i < level; ++i) {
+    const auto& m = hierarchy[i];
+    auto M = size_t(pow(pow(2, i) + 1, D));
+    auto N = size_t(pow(pow(2, i + 1) + 1, D));
+    if (m->M() != M || m->N() != N) {
+      std::string error_msg = "Transfer dimensions are " +
+                              std::to_string(m->M()) + "," +
+                              std::to_string(m->N()) + " but expected was " +
+                              std::to_string(M) + "," + std::to_string(N);
+      DUNE_THROW(Exception, error_msg);
+      return false;
+    }
+  }
+  return true;
+}
+
+template <class Grid, size_t D>
+bool test(const Grid& grid, std::string id) {
+  std::cout << "Testing " << id << "grid in " << D << "D...";
+  try {
+    test<Grid, D>(grid);
+    std::cout << " succeeded." << std::endl;
+  } catch (Exception e) {
+    std::cout << " failed: " << e << std::endl;
+    return false;
+  }
+  return true;
+}
+
+template <class Grid, size_t D>
+bool testWithGrid(std::string id = "") {
+  auto grid = std::shared_ptr<Grid>(createGrid<Grid, D>());
+  return test<Grid, D>(*grid, id);
+}
+
+#if HAVE_DUNE_SUBGRID
+template <class HostGrid, size_t D>
+bool testWithSubGrid(std::string id = "") {
+  auto hostGrid = std::shared_ptr<HostGrid>(createGrid<HostGrid, 2>());
+  using Grid = SubGrid<2, HostGrid, false>;
+  Grid grid(*hostGrid);
+  return test<Grid, D>(grid, std::string("Subgrid of ") + id);
+}
+#endif
+
+template <size_t D>
+using MyALUGrid = Dune::ALUGrid<2, 2, ALUGridElementType::simplex,
+                                ALUGridRefinementType::nonconforming>;
+
+template <size_t D>
+bool testDim() {
+  bool passed = true;
+  passed = passed && testWithGrid<Dune::UGGrid<D>, D>("UG");
+  passed = passed && testWithGrid<MyALUGrid<D>, D>("ALU");
+
+#if HAVE_DUNE_SUBGRID
+  passed = passed && testWithSubGrid<Dune::UGGrid<D>, D>("UG");
+  passed = passed && testWithSubGrid<MyALUGrid<D>, D>("ALU");
+#endif
+  return passed;
+}
+
+int main(int argc, char* argv[]) {
+  bool passed = true;
+  Dune::MPIHelper::instance(argc, argv);
+
+  passed = passed && testDim<2>();
+  //  passed = passed && testDim<3>();
+
+  return passed ? 0 : 1;
+}