diff --git a/src/main/java/no/ntnu/idatt1002/demo/data/recipes/FoodItem.java b/src/main/java/no/ntnu/idatt1002/demo/data/recipes/FoodItem.java
new file mode 100644
index 0000000000000000000000000000000000000000..94c956d7149385d2a83597e69b90c4849081cf11
--- /dev/null
+++ b/src/main/java/no/ntnu/idatt1002/demo/data/recipes/FoodItem.java
@@ -0,0 +1,22 @@
+package no.ntnu.idatt1002.demo.data.recipes;
+
+public enum FoodItem {
+
+    ONION("onion"),
+    MINCED_MEAT("minced meat"),
+    POTATO("potatoes"),
+    YELLOW_CHEESE("yellow cheese"),
+    WHEAT_FLOUR("wheat flour"),
+    MILK("milk"),
+    TOMATO("tomato"),
+    ORANGE("orange"),
+    LEMON("lemon"),
+    SALSA_SAUCE("salsa sauce")
+    ;
+
+    public final String label;
+
+    FoodItem(String label) {
+        this.label = label;
+    }
+}
diff --git a/src/main/java/no/ntnu/idatt1002/demo/data/recipes/Ingredient.java b/src/main/java/no/ntnu/idatt1002/demo/data/recipes/Ingredient.java
new file mode 100644
index 0000000000000000000000000000000000000000..50c850574dc549e12891bc41ed2c5f512225c8bb
--- /dev/null
+++ b/src/main/java/no/ntnu/idatt1002/demo/data/recipes/Ingredient.java
@@ -0,0 +1,123 @@
+package no.ntnu.idatt1002.demo.data.recipes;
+
+import java.util.Objects;
+
+/**
+ * The Ingredient class represents an ingredient that can be part of a recipe in real life and/or
+ * be available to the user in real life. When the ingredient is part of a recipe, the subclass called
+ * RecipeIngredient is used. An ingredient belongs to a food type among the values of the FoodItem enum class.
+ * Examples are onion, tomato, spaghetti, chicken etc. The ingredient is provided in a specific amount and unit
+ * of measure.
+ *
+ * @author hannesofie
+ */
+public class Ingredient {
+
+    private FoodItem foodType;
+    private double amount;
+    private MeasuringUnit unit;
+
+    /**
+     * The constructor of a new Ingredient object takes in three mandatory fields; ingredient type as defined in
+     * the enum class FoodItem, an amount and a unit of measure defined in the enum class MeasuringUnit. The amount
+     * must be a positive number.
+     * @param ingredient What type of food the ingredient is.
+     * @param amount The amount of the ingredient.
+     * @param unit The unit of measure of the given amount of the ingredient.
+     */
+    public Ingredient(FoodItem ingredient, double amount, MeasuringUnit unit) {
+        if(ingredient == null | amount <= 0.0f | unit == null) {
+            throw new IllegalArgumentException("The ingredient must have a type, amount and measuring unit.");
+        }
+        this.foodType = ingredient;
+        this.amount = amount;
+        this.unit = unit;
+    }
+
+    /**
+     * The method returns the food type that the ingredient belongs to among the valid types in the FoodItem enum class.
+     * @return What type of food the ingredient is.
+     */
+    public FoodItem getFoodType() {
+        return foodType;
+    }
+
+    public void setFoodType(FoodItem foodType) {
+        if(foodType == null) {
+            throw new IllegalArgumentException("The food type must be set to a valid value of FoodItem.");
+        }
+        this.foodType = foodType;
+    }
+
+    /**
+     * The method returns the amount of an ingredient as the datatype double.
+     * @return The amount of an ingredient as double.
+     */
+    public double getAmount() {
+        return amount;
+    }
+
+    /**
+     * The method takes in a new amount as a double and sets the ingredient's amount field equal to this value.
+     * If the provided value is not a positive double, an IllegalArgumentException is thrown.
+     * @param amount The amount of an ingredient as double.
+     */
+    public void setAmount(double amount) {
+        if(amount <= 0.0f) {
+            throw new IllegalArgumentException("The amount of an ingredient cannot be zero or negative.");
+        }
+        this.amount = amount;
+    }
+
+    /**
+     * The method returns the unit of measure of the ingredient as a value of the MeasuringUnit enum class.
+     * @return The unit of measure of the given amount of the ingredient.
+     */
+    public MeasuringUnit getUnit() {
+        return unit;
+    }
+
+    /**
+     * The method takes in a value of the MeasuringUnit enum class and sets the ingredient's unit equal to this
+     * value.
+     * @param unit The unit of measure of the given amount of the ingredient.
+     */
+    public void setUnit(MeasuringUnit unit) {
+        if(unit == null) {
+            throw new IllegalArgumentException("The food's measuring unit must be set to a valid value of MeasuringUnit.");
+        }
+        this.unit = unit;
+    }
+
+    /**
+     * The method returns a String representation of an Ingredient object, listing its type, amount and unit.
+     * @return A String representation of the ingredient object.
+     */
+    @Override
+    public String toString() {
+        return "Ingredient{" +
+                "foodType=" + foodType.label +
+                ", amount=" + amount +
+                ", unit=" + unit.label +
+                '}';
+    }
+
+    /**
+     * The method checks if a given object is equal to the ingredient object.
+     * If the object is of the same class as well as having the same value for each class field,
+     * the object is equal to the Ingredient.
+     * @param o An Object to which the Ingredient should be compared.
+     * @return True if the object is equivalent to the Ingredient, false otherwise.
+     */
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (!(o instanceof Ingredient that)) return false;
+        return Double.compare(that.amount, amount) == 0 && foodType == that.foodType && unit == that.unit;
+    }
+
+/*    @Override
+    public int hashCode() {
+        return Objects.hash(foodType, amount, unit);
+    }*/
+}
diff --git a/src/main/java/no/ntnu/idatt1002/demo/data/recipes/IngredientsAtHand.java b/src/main/java/no/ntnu/idatt1002/demo/data/recipes/IngredientsAtHand.java
new file mode 100644
index 0000000000000000000000000000000000000000..72318cd4f29e3228c6300bcd17bba64beb585805
--- /dev/null
+++ b/src/main/java/no/ntnu/idatt1002/demo/data/recipes/IngredientsAtHand.java
@@ -0,0 +1,84 @@
+package no.ntnu.idatt1002.demo.data.recipes;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * The IngredientsAtHand class contains a collection of Ingredient objects that are currently available to the user.
+ * Only one instance of each ingredient type may exist in the collection. If an ingredient is already present in the
+ * collection, the old will be replaced by the new.
+ *
+ * @author hannesofie
+ */
+public class IngredientsAtHand {
+
+    private final List<Ingredient> ingredientsAtHand = new ArrayList<>();
+
+    /**
+     * The method returns the collection of ingredients at hand as an arraylist of ingredient objects.
+     * @return The collection of ingredients at hand to the user.
+     */
+    public List<Ingredient> getIngredientsAtHand() {
+        return ingredientsAtHand;
+    }
+
+    /**
+     * The method takes in an ingredient object and adds it to the collection of ingredients at hand.
+     * @param ingredient The ingredient object to add to the collection of ingredients at hand.
+     */
+    public void addIngredient(Ingredient ingredient) {
+        this.ingredientsAtHand.add(ingredient);
+    }
+
+    /**
+     * Returns null if no ingredient of the requested type is found in the collection.
+     * @param ingredientType What type of food the ingredient is.
+     * @return The ingredient of the specified type found among the ingredients at hand, null otherwise.
+     */
+    public Ingredient getIngredient(FoodItem ingredientType) {
+        if(ingredientType == null) return null;
+        return this.getIngredientsAtHand().stream()
+                .filter((ingredient) -> ingredient.getFoodType() == ingredientType)
+                .findFirst().orElse(null);
+    }
+
+    /**
+     * The method takes in three parameters. The method first checks if the Ingredient is at hand in the first place.
+     * If it is, the old amount and unit of this ingredient are replaced by the provided amount and unit if they
+     * differ. If not, the ingredient is left as is. If the ingredient is not in the collection,
+     * @param ingredientType What type of food the ingredient is.
+     * @param amount The amount of the ingredient.
+     * @return True if Ingredient is successfully altered or added, false if not.
+     */
+    public boolean alterIngredient(FoodItem ingredientType, double amount, MeasuringUnit unit) {
+        //TODO: Consider handling exceptions differently.
+        if(ingredientsAtHand.stream().anyMatch((ingredient) -> ingredient.getFoodType() == ingredientType)) {
+            try {
+                getIngredient(ingredientType).setAmount(amount);
+                getIngredient(ingredientType).setUnit(unit);
+
+            } catch (IllegalArgumentException e) {
+                return false;
+            }
+        } else {
+            try {
+                addIngredient(new Ingredient(ingredientType, amount, unit));
+            } catch (IllegalArgumentException e) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * The method takes in a value of the FoodItem enum as a parameter and removes it from the collection of
+     * ingredients at hand if it exists and returns true. If no ingredient of the given type was found in the
+     * collection, false is returned.
+     * @param ingredientType What type of food the ingredient is.
+     * @return True if the ingredient was found among the ingredients at hand and removed, false otherwise.
+     */
+    public boolean removeIngredient(FoodItem ingredientType) {
+        return ingredientsAtHand.removeIf((ingredient) -> ingredient.getFoodType() == ingredientType);
+    }
+
+}
diff --git a/src/main/java/no/ntnu/idatt1002/demo/data/recipes/MeasuringUnit.java b/src/main/java/no/ntnu/idatt1002/demo/data/recipes/MeasuringUnit.java
new file mode 100644
index 0000000000000000000000000000000000000000..83f664cd4fc99285c6fc18fffc0b910c633b7412
--- /dev/null
+++ b/src/main/java/no/ntnu/idatt1002/demo/data/recipes/MeasuringUnit.java
@@ -0,0 +1,18 @@
+package no.ntnu.idatt1002.demo.data.recipes;
+
+public enum MeasuringUnit {
+
+    DL("dl."),
+    L("l."),
+    TSP("tsp."),
+    TBS("tbs."),
+    GR("gr."),
+    KG("kg."),
+    PC("pieces");
+
+    public final String label;
+
+    MeasuringUnit(String label) {
+        this.label = label;
+    }
+}
diff --git a/src/main/java/no/ntnu/idatt1002/demo/data/recipes/Recipe.java b/src/main/java/no/ntnu/idatt1002/demo/data/recipes/Recipe.java
new file mode 100644
index 0000000000000000000000000000000000000000..dd6330f177983aa20d7ae9f548983214d4014f1a
--- /dev/null
+++ b/src/main/java/no/ntnu/idatt1002/demo/data/recipes/Recipe.java
@@ -0,0 +1,119 @@
+package no.ntnu.idatt1002.demo.data.recipes;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+// Method in case we want to check if also the amount is enough for the recipe.
+// Recipes without any ingredients can be showed among all ingredients, but not in suggestion based on ingredients
+// at hand.
+//TODO: Record?
+public class Recipe {
+
+    private String name = "";
+    private List<RecipeIngredient> ingredientList = new ArrayList<>();
+    private String instructions = "";
+
+    public Recipe(String name, String description ) {
+        if(name.isBlank() | description.isBlank()) {
+            throw new IllegalArgumentException("The recipe must have a name and a description.");
+        }
+        this.name = name;
+        this.instructions = description;
+    }
+
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        if(name.isBlank()) {
+            throw new IllegalArgumentException("The recipe name cannot be left blank.");
+        }
+        this.name = name;
+    }
+
+    public List<RecipeIngredient> getIngredientList() {
+        return ingredientList;
+    }
+
+    public String getInstructions() {
+        return instructions;
+    }
+
+    public void setInstructions(String instructions) {
+        if(instructions.isBlank()) {
+            throw new IllegalArgumentException("The recipe instructions cannot be left blank.");
+        }
+        this.instructions = instructions;
+    }
+
+
+ /*   public void addIngredients(ArrayList<RecipeIngredient> ingredients) {
+        ingredients.forEach((ingredient) -> this.ingredientList.add(ingredient));
+    }*/
+
+    //TODO: Make interface for "collects ingredients" and do deep copy.
+
+    public RecipeIngredient getIngredient(FoodItem ingredientType) {
+        if(ingredientType == null) return null;
+        return this.getIngredientList().stream()
+                .filter((ingredient) -> ingredient.getFoodType() == ingredientType)
+                .findFirst().orElse(null);
+    }
+
+
+    public boolean addIngredient(FoodItem ingredientType, double amount, MeasuringUnit unit) {
+        if(ingredientList.stream().anyMatch((ingredient) -> ingredient.getFoodType() == ingredientType)) {
+            try {
+                getIngredient(ingredientType).setAmount(amount);
+                getIngredient(ingredientType).setUnit(unit);
+
+            } catch (IllegalArgumentException e) {
+                return false;
+            }
+        } else {
+            try {
+                this.ingredientList.add(new RecipeIngredient(ingredientType, amount, unit));
+            } catch (IllegalArgumentException e) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * The functionality may be expanded upon in order to also check if the amount is sufficient for the current recipe.
+     * @param ingredientsAtHand
+     */
+    public void updateIngredientStatus(IngredientsAtHand ingredientsAtHand) {
+        // Will need a supporting class for converting between units to be accurate.
+       if(ingredientsAtHand == null) {
+           throw new NullPointerException("The ingredients at hand object must exist");
+       } else if (ingredientsAtHand.getIngredientsAtHand().size() < 1) {
+           throw new IllegalArgumentException("The collection of ingredients at hand is empty.");
+       } else {
+           ingredientList.forEach((inRecipe) -> {
+               ingredientsAtHand.getIngredientsAtHand().forEach((atHand) -> {
+                   if(inRecipe.getFoodType() == atHand.getFoodType()) {
+                       inRecipe.setAtHand(true);
+                   }
+               });
+           });
+       }
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        Recipe recipe = (Recipe) o;
+        return Objects.equals(name, recipe.name);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(name, ingredientList, instructions);
+    }
+}
diff --git a/src/main/java/no/ntnu/idatt1002/demo/data/recipes/RecipeIngredient.java b/src/main/java/no/ntnu/idatt1002/demo/data/recipes/RecipeIngredient.java
new file mode 100644
index 0000000000000000000000000000000000000000..36850d072b18816f5bdd231400eedef305e8cf84
--- /dev/null
+++ b/src/main/java/no/ntnu/idatt1002/demo/data/recipes/RecipeIngredient.java
@@ -0,0 +1,44 @@
+package no.ntnu.idatt1002.demo.data.recipes;
+
+/**
+ * The RecipeIngredient class is an extension of the Ingredient class  used as part of recipes
+ * that also stored the boolean value 'atHand'. This value can be set to true whenever the given ingredient,
+ * being part of a recipe, is also at hand to the user. Ingredients that the user has available are stored in
+ * the IngredientsAtHand class.
+ *
+ * @author hannesofie
+ */
+public class RecipeIngredient extends Ingredient{
+
+    private boolean atHand = false;
+
+    /**
+     * The constructor of a RecipeIngredient object inherits from the superclass Ingredient. The additional 'atHand'
+     * field is set to false ar default.
+     * @param ingredient What type of food the ingredient is.
+     * @param amount The amount of the ingredient.
+     * @param unit The unit of measure of the given amount of the ingredient.
+     */
+    public RecipeIngredient(FoodItem ingredient, double amount, MeasuringUnit unit) {
+        super(ingredient, amount, unit);
+    }
+
+    /**
+     * The method returns the boolean value of the atHand field for the ingredient. If the ingredient being part of
+     * a recipe is also contained in the collection of ingredients at hand to the user, true is returned, if not,
+     * false is returned.
+     * @return True of the current recipe ingredient is available to the user.
+     */
+    public boolean isAtHand() {
+        return atHand;
+    }
+
+    /**
+     * The method sets the value of the atHand field for the ingredient to either true or false.
+     * @param atHand
+     */
+    public void setAtHand(boolean atHand) {
+        this.atHand = atHand;
+    }
+
+}
diff --git a/src/main/java/no/ntnu/idatt1002/demo/data/recipes/RecipeRegister.java b/src/main/java/no/ntnu/idatt1002/demo/data/recipes/RecipeRegister.java
new file mode 100644
index 0000000000000000000000000000000000000000..1ec98e95879698ac7e6088f46f18e54a2bf67062
--- /dev/null
+++ b/src/main/java/no/ntnu/idatt1002/demo/data/recipes/RecipeRegister.java
@@ -0,0 +1,31 @@
+package no.ntnu.idatt1002.demo.data.recipes;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class RecipeRegister {
+
+    private final List<Recipe> recipes = new ArrayList<>();
+
+
+    //TODO: Copy-constructor
+
+    public List<Recipe> getRecipes() {
+        return recipes;
+    }
+
+    public void addRecipe (Recipe recipe) {
+        if(recipes.contains(recipe)) {
+            throw new IllegalArgumentException("The recipe already exists in the register."); // Or just replace?
+        } else if (recipe == null) {
+            throw new NullPointerException("The recipe cannot be null.");
+        }
+        this.recipes.add(recipe);
+    }
+
+    public Recipe getRecipe(String name) {
+        return recipes.stream().
+                filter((recipe) -> recipe.getName().equals(name))
+                        .findFirst().orElse(null);
+    }
+}
diff --git a/src/test/java/no/ntnu/idatt1002/demo/data/recipes/IngredientTest.java b/src/test/java/no/ntnu/idatt1002/demo/data/recipes/IngredientTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..79dd0439298817a773fc8ac9c6c70f19575c0957
--- /dev/null
+++ b/src/test/java/no/ntnu/idatt1002/demo/data/recipes/IngredientTest.java
@@ -0,0 +1,76 @@
+package no.ntnu.idatt1002.demo.data.recipes;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+class IngredientTest {
+
+    Ingredient testIngredient;
+
+    @BeforeEach
+    void beforeEach() {
+        testIngredient = new Ingredient(FoodItem.ONION, 0.5f, MeasuringUnit.KG);
+    }
+
+    @Test
+    @DisplayName("The constructor creates an ingredient object successfully")
+    void constructValidIngredient() {
+        Ingredient validIngredient = new Ingredient(FoodItem.ONION, 1, MeasuringUnit.KG);
+        assertEquals(validIngredient, new Ingredient(FoodItem.ONION, 1, MeasuringUnit.KG));
+    }
+
+    @Test
+    @DisplayName("The constructor throws exceptions for illegal input.")
+    void constructorThrowsExceptionsWhenItShould() {
+        assertThrows(IllegalArgumentException.class, () -> new Ingredient(null, 2, MeasuringUnit.DL));
+        assertThrows(IllegalArgumentException.class, () -> new Ingredient(FoodItem.ONION, -5, MeasuringUnit.DL));
+        assertThrows(IllegalArgumentException.class, () -> new Ingredient(FoodItem.ONION, 0, MeasuringUnit.DL));
+        assertThrows(IllegalArgumentException.class, () -> new Ingredient(FoodItem.ONION, 2, null));
+    }
+
+    @Test
+    @DisplayName("Change of food type works for valid food type.")
+    void setFoodTypeWorksForValidType() {
+        testIngredient.setFoodType(FoodItem.LEMON);
+        assertEquals(new Ingredient(FoodItem.LEMON, 0.5f, MeasuringUnit.KG), testIngredient);
+    }
+
+    @Test
+    @DisplayName("Change of food type to invalid type throws exception.")
+    void setFoodTypeThrowsException() {
+        assertThrows(IllegalArgumentException.class, () -> testIngredient.setFoodType(null));
+    }
+
+    @Test
+    @DisplayName("Change of food amount works for valid amount.")
+    void setAmountWorksForValidAmount() {
+        testIngredient.setAmount(2.5);
+        assertEquals(new Ingredient(FoodItem.ONION, 2.5f, MeasuringUnit.KG), testIngredient);
+    }
+
+    @Test
+    @DisplayName("Change of food amount to invalid amount throws exception.")
+    void setAmountThrowsException() {
+        assertThrows(IllegalArgumentException.class, () -> testIngredient.setAmount(0));
+        assertThrows(IllegalArgumentException.class, () -> testIngredient.setAmount(-1));
+    }
+
+    @Test
+    @DisplayName("Change of measuring unit works for valid unit.")
+    void setUnitWorksForValidUnit() {
+        testIngredient.setUnit(MeasuringUnit.TBS);
+        assertEquals(new Ingredient(FoodItem.ONION, 0.5f, MeasuringUnit.TBS), testIngredient);
+    }
+
+    @Test
+    @DisplayName("Change of measuring to invalid unit throws exception.")
+    void setUnitThrowsException() {
+        assertThrows(IllegalArgumentException.class, () -> testIngredient.setUnit(null));
+    }
+
+//TODO: Test for equals method?
+
+}
\ No newline at end of file
diff --git a/src/test/java/no/ntnu/idatt1002/demo/data/recipes/IngredientsAtHandTest.java b/src/test/java/no/ntnu/idatt1002/demo/data/recipes/IngredientsAtHandTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..369d7c43de2309fda39160a9cbe50b566075d800
--- /dev/null
+++ b/src/test/java/no/ntnu/idatt1002/demo/data/recipes/IngredientsAtHandTest.java
@@ -0,0 +1,92 @@
+package no.ntnu.idatt1002.demo.data.recipes;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+class IngredientsAtHandTest {
+
+    IngredientsAtHand ingredientsAtHand = new IngredientsAtHand();
+
+    @BeforeEach
+    void beforeEach() {
+        ingredientsAtHand.addIngredient(new Ingredient(FoodItem.LEMON, 3, MeasuringUnit.PC));
+        ingredientsAtHand.addIngredient(new Ingredient(FoodItem.MILK, 1.5f, MeasuringUnit.L));
+        ingredientsAtHand.addIngredient(new Ingredient(FoodItem.MINCED_MEAT, 400, MeasuringUnit.GR));
+
+    }
+
+    @Test
+    @DisplayName("The getIngredient method returns the correct ingredient.")
+    void getIngredientReturnsSuccessfully() {
+        assertEquals(new Ingredient(FoodItem.LEMON, 3, MeasuringUnit.PC),
+                ingredientsAtHand.getIngredient(FoodItem.LEMON));
+
+    }
+
+    @Test
+    @DisplayName("The getIngredient method returns null if the ingredient is not in the collection.")
+    void getIngredientReturnsNullWhenNotFoundOrNull(){
+        assertNull(ingredientsAtHand.getIngredient(FoodItem.ONION));
+        assertNull(ingredientsAtHand.getIngredient(null));
+    }
+
+
+    @Test
+    @DisplayName("Altering ingredient successfully and return true.")
+    void alterIngredientSuccessfully() {
+        assertNotEquals(new Ingredient(FoodItem.ONION, 500, MeasuringUnit.GR),
+                ingredientsAtHand.getIngredient(FoodItem.ONION));
+
+        assertTrue(ingredientsAtHand.alterIngredient(FoodItem.ONION, 500, MeasuringUnit.GR));
+
+        assertEquals(new Ingredient(FoodItem.ONION, 500, MeasuringUnit.GR),
+                ingredientsAtHand.getIngredient(FoodItem.ONION));
+
+    }
+
+    @Test
+    @DisplayName("Altering ingredient that does not yet exist in collection adds it and returns true.")
+    void alterNewIngredientAddsIt() {
+        int ingredientsAtStart = ingredientsAtHand.getIngredientsAtHand().size();
+        assertTrue(ingredientsAtHand.alterIngredient(FoodItem.ORANGE, 8, MeasuringUnit.PC));
+
+        assertEquals(ingredientsAtStart + 1, ingredientsAtHand.getIngredientsAtHand().size());
+    }
+
+    @Test
+    @DisplayName("Attempting to alter ingredient in illegal way does not alter the collection and returns false.")
+    void alterIngredientUnchangedForInvalidChange() {
+        assertFalse(ingredientsAtHand.alterIngredient(null, 350, MeasuringUnit.GR));
+        assertEquals(new Ingredient(FoodItem.LEMON, 3, MeasuringUnit.PC),
+                ingredientsAtHand.getIngredient(FoodItem.LEMON));
+    }
+
+    @Test
+    @DisplayName("Altering an ingredients without changing values, leaves no change on the collection and returns true.")
+    void alterNothingLeavesCollectionIntact() {
+        int ingredientsAtStart = ingredientsAtHand.getIngredientsAtHand().size();
+
+         assertTrue(ingredientsAtHand.alterIngredient(FoodItem.LEMON, 3, MeasuringUnit.PC));
+
+        assertEquals(ingredientsAtStart, ingredientsAtHand.getIngredientsAtHand().size());
+    }
+
+    @Test
+    @DisplayName("Ingredient is removed successfully and true is returned.")
+    void removeIngredientSuccessfully() {
+        int ingredientsAtStart = ingredientsAtHand.getIngredientsAtHand().size();
+        assertTrue(ingredientsAtHand.removeIngredient(FoodItem.LEMON));
+        assertEquals(ingredientsAtStart-1, ingredientsAtHand.getIngredientsAtHand().size());
+    }
+
+    @Test
+    @DisplayName("Removing ingredient that is not in the collection, leaves it unchanged and returns false.")
+    void removeIngredientNotInCollection() {
+
+        assertFalse(ingredientsAtHand.removeIngredient(FoodItem.SALSA_SAUCE));
+    }
+
+}
\ No newline at end of file
diff --git a/src/test/java/no/ntnu/idatt1002/demo/data/recipes/RecipeRegisterTest.java b/src/test/java/no/ntnu/idatt1002/demo/data/recipes/RecipeRegisterTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..4176a2451f7ed7ba28f9653b5f77ef1ba00abd49
--- /dev/null
+++ b/src/test/java/no/ntnu/idatt1002/demo/data/recipes/RecipeRegisterTest.java
@@ -0,0 +1,45 @@
+package no.ntnu.idatt1002.demo.data.recipes;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+class RecipeRegisterTest {
+
+    RecipeRegister myRecipes;
+
+    @BeforeEach
+    void beforeEach() {
+        myRecipes = new RecipeRegister();
+        myRecipes.addRecipe(new Recipe("Pasta al Limone", "Instructions"));
+    }
+
+    @Test
+    @DisplayName("Adding recipe to register successfully.")
+    void addRecipeToRegister() {
+        int numberOfRecipes = myRecipes.getRecipes().size();
+        myRecipes.addRecipe(new Recipe("Carbonara", "Instructions"));
+        assertEquals(numberOfRecipes + 1, myRecipes.getRecipes().size());
+    }
+
+    @Test
+    @DisplayName("Throw exception when adding already registered recipe.")
+    void recipeAlreadyInRegister() {
+        assertThrows(IllegalArgumentException.class, () -> myRecipes.addRecipe( new Recipe("Pasta al Limone", "Instructions")));
+    }
+
+    @Test
+    @DisplayName("Throw exception when adding null recipe.")
+    void addNullRecipe() {
+        assertThrows(NullPointerException.class, () -> myRecipes.addRecipe(null));
+    }
+
+    @Test
+    @DisplayName("Returns correct recipe based on name.")
+    void getRecipeByName() {
+        assertEquals(new Recipe("Pasta al Limone", "Instructions"), myRecipes.getRecipe("Pasta al Limone"));
+    }
+
+}
\ No newline at end of file
diff --git a/src/test/java/no/ntnu/idatt1002/demo/data/recipes/RecipeTest.java b/src/test/java/no/ntnu/idatt1002/demo/data/recipes/RecipeTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..46d4955720b089e6391f3e5f0aaa5f70fb014b06
--- /dev/null
+++ b/src/test/java/no/ntnu/idatt1002/demo/data/recipes/RecipeTest.java
@@ -0,0 +1,117 @@
+package no.ntnu.idatt1002.demo.data.recipes;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+class RecipeTest {
+
+    Recipe recipe;
+
+    @BeforeEach
+    void beforeEach() {
+        recipe = new Recipe("Meat, cheese and potatoes", "Instructions");
+
+        recipe.addIngredient(FoodItem.MINCED_MEAT, 500, MeasuringUnit.GR);
+        recipe.addIngredient(FoodItem.POTATO, 750, MeasuringUnit.GR);
+        recipe.addIngredient(FoodItem.YELLOW_CHEESE, 2, MeasuringUnit.DL);
+
+    }
+
+    @Test
+    @DisplayName("Constructor creates Recipe successfully.")
+    void constructorCreatesRecipe() {
+        assertEquals(recipe, new Recipe("Meat, cheese and potatoes", "Instructions"));
+        // Recipes are equal if name and Instructions are equal.
+    }
+
+    @Test
+    @DisplayName("Constructor throws exception for empty name or instruction.")
+    void constructorThrowsException() {
+        assertThrows(IllegalArgumentException.class, () -> new Recipe("", "Instructions"));
+        assertThrows(IllegalArgumentException.class, () -> new Recipe("Name", ""));
+
+    }
+
+    @Test
+    @DisplayName("Can change name of recipe successfully.")
+    void setNameSuccessfully() {
+        String newName = "Meat and cheese";
+        recipe.setName(newName);
+        assertEquals(newName, recipe.getName());
+    }
+
+    @Test
+    @DisplayName("Throws exception when name set to empty string.")
+    void setNameEmptyThrowsException() {
+        assertThrows(IllegalArgumentException.class, () -> recipe.setName(" "));
+    }
+
+    @Test
+    @DisplayName("Can change instructions of recipe successfully.")
+    void setInstructionsSuccessfully() {
+        String newInstruction = "New instructions";
+        recipe.setInstructions(newInstruction);
+        assertEquals(newInstruction, recipe.getInstructions());
+    }
+
+    @Test
+    @DisplayName("Throws exception when Instructions set to empty string.")
+    void setInstructionsEmptyThrowsException() {
+        assertThrows(IllegalArgumentException.class, () -> recipe.setInstructions(""));
+    }
+
+
+    @Test
+    @DisplayName("Ingredient is added to recipe successfully.")
+    void addNewIngredient() {
+        int ingredientsInRecipe = recipe.getIngredientList().size();
+        assertTrue(recipe.addIngredient(FoodItem.LEMON, 1, MeasuringUnit.PC));
+        assertEquals(ingredientsInRecipe + 1, recipe.getIngredientList().size());
+    }
+
+    @Test
+    @DisplayName("Ingredient already in recipe does not alter and returns true.")
+    void addAlreadyIncludedIngredient() {
+        int ingredientsInRecipe = recipe.getIngredientList().size();
+        assertTrue(recipe.addIngredient(FoodItem.MINCED_MEAT, 500, MeasuringUnit.GR));
+        assertEquals(ingredientsInRecipe, recipe.getIngredientList().size());
+    }
+
+    @Test
+    @DisplayName("Invalid ingredient change is not made and false is returned.")
+    void addInvalidIngredientReturnsFalse() {
+        int ingredientsInRecipe = recipe.getIngredientList().size();
+        assertFalse(recipe.addIngredient(null, 500, MeasuringUnit.GR));
+        assertEquals(ingredientsInRecipe, recipe.getIngredientList().size());
+    }
+
+
+    @Test
+    @DisplayName("Updating ingredient status works as expected.")
+    void updateIngredientStatus() {
+        IngredientsAtHand inFridge = new IngredientsAtHand();
+        inFridge.addIngredient(new Ingredient(FoodItem.MINCED_MEAT, 400, MeasuringUnit.GR));
+        inFridge.addIngredient(new Ingredient(FoodItem.YELLOW_CHEESE, 500, MeasuringUnit.GR));
+
+
+        recipe.getIngredientList().forEach((ingredient) -> assertFalse(ingredient.isAtHand()));
+        recipe.updateIngredientStatus(inFridge);
+
+        assertTrue(recipe.getIngredient(FoodItem.MINCED_MEAT).isAtHand());
+        assertTrue(recipe.getIngredient(FoodItem.YELLOW_CHEESE).isAtHand());
+        assertFalse(recipe.getIngredient(FoodItem.POTATO).isAtHand());
+    }
+
+    @Test
+    @DisplayName("Update of ingredient status based on empty or null ingredients at hand collection.")
+    void nullOrEmptyIngredientsAtHand() {
+        IngredientsAtHand emptyFridge = new IngredientsAtHand();
+
+        assertThrows(NullPointerException.class, () -> recipe.updateIngredientStatus(null));
+        assertThrows(IllegalArgumentException.class, () -> recipe.updateIngredientStatus(emptyFridge));
+    }
+
+}
\ No newline at end of file