如何在使用依赖工厂方法时解决递归问题

时间:2017-06-30 13:03:19

标签: java unit-testing

我试图在单个Java-Class中获取单元测试的所有参考数据。想出了以下概念。 我现在唯一的问题就是我不能打电话,例如预订 - 方法因为我有一个无限循环来调用房间 - 方法。

我不知道如何解决这个问题。

package model;

import com.appenetic.fame.model.Booking;
import com.appenetic.fame.model.Building;
import com.appenetic.fame.model.Floor;
import com.appenetic.fame.model.Inventory;
import com.appenetic.fame.model.InventoryCollection;
import com.appenetic.fame.model.Location;
import com.appenetic.fame.model.LocationCollection;
import com.appenetic.fame.model.Room;
import com.appenetic.fame.model.Tag;
import com.appenetic.fame.model.TimeFrame;

import java.util.Date;

/**
 * Created by saschaheld on 30.06.17.
 */

public class ReferenceData {
    public static Room room() { //done
        Room referenceRoom = new Room();
        referenceRoom.setRoomId(100);
        referenceRoom.setRoomIdentifier("Room XXXX");
        referenceRoom.setRoomNumber("Room Number XXX");
        referenceRoom.setDoorPlate("Door Plate XXX");
        referenceRoom.setRoomZone("Room Zone XXX");
        referenceRoom.setBarcode("2345234");
        referenceRoom.setSeats("20 Seats");
        referenceRoom.setStatus(Room.RoomStatus.Available);
        referenceRoom.setFloor(floor());
        referenceRoom.addTimeFrame(timeFrame());
        referenceRoom.addInventory(inventory());
        referenceRoom.setLocationCollection(locationCollection());

        return referenceRoom;
    }

    public static Inventory inventory() { // done
        Inventory referenceInventory = new Inventory();
        referenceInventory.setInventoryId(1);
        referenceInventory.setInventoryIdentifier("0235234");
        referenceInventory.setAssetImagePath("picture.png");
        referenceInventory.setDescriptionShort("Short description");
        referenceInventory.setDescriptionLong("Long description");
        referenceInventory.setManufacturer("Manufacturer");
        referenceInventory.setScanDate(new Date());
        referenceInventory.setStatus(Inventory.INVENTORY_STATUS_NOT_SET);
        referenceInventory.setGpsLat((float)40.2);
        referenceInventory.setGpsLng((float) 10.34);
        referenceInventory.setGpsAccuracy(10);
        referenceInventory.setTagType(Tag.TagType.RFID);
        referenceInventory.setTagValue("XXXXXX");
        referenceInventory.setRoom(room());
        referenceInventory.setInventoryCollection(inventoryCollection());

        return referenceInventory;
    }

    public static InventoryCollection inventoryCollection() { //done
        InventoryCollection inventoryCollection = new InventoryCollection();
        inventoryCollection.setInventoryCollectionId(34);
        inventoryCollection.setCreatedAt(new Date());
        inventoryCollection.addInventory(inventory());

        return inventoryCollection;
    }

    public static TimeFrame timeFrame() { //done
        TimeFrame referenceTimeFrame = new TimeFrame();
        referenceTimeFrame.setTimeFrameId(10);
        referenceTimeFrame.setFrom(new Date());
        referenceTimeFrame.setTo(new Date());
        referenceTimeFrame.setMinutes(10.2);
        referenceTimeFrame.setRoom(room());

        return referenceTimeFrame;
    }

    public static Floor floor() { //done
        Floor referenceFloor = new Floor();
        referenceFloor.setFloorId(99);
        referenceFloor.setFloorIdentifier("Floor XXXX");
        referenceFloor.setName("Top floor");
        referenceFloor.setBuilding(building());
        referenceFloor.addRoom(room());

        return referenceFloor;
    }

    public static Building building() { //done
        Building referenceBuilding = new Building();
        referenceBuilding.setBuildingId(200);
        referenceBuilding.setName("High building");
        referenceBuilding.setBuildingIdentifier("Building identifier XXX");
        referenceBuilding.setLocation(location());
        referenceBuilding.addFloor(floor());

        return referenceBuilding;
    }

    public static Location location() { //done
        Location referenceLocation = new Location();
        referenceLocation.setLocationId(10);
        referenceLocation.setLocationIdentifier("23042134");
        referenceLocation.setName("Reference Location");
        referenceLocation.setLocationCollection(locationCollection());
        referenceLocation.addBuilding(building());

        return referenceLocation;
    }

    public static LocationCollection locationCollection() { //done
        LocationCollection referenceLocationCollection = new LocationCollection();
        referenceLocationCollection.setLocationCollectionId(10);
        referenceLocationCollection.setHashValue("XXX-XXX-XXX");
        referenceLocationCollection.setRoom(room());
        referenceLocationCollection.addLocation(location());

        return referenceLocationCollection;
    }

    public static Booking booking() { //done
        Booking referenceBooking = new Booking();
        referenceBooking.setBookingId(101);
        referenceBooking.setIdentifier("Booking XXX");
        referenceBooking.setBookingNumber("XXXXXX");
        referenceBooking.setTitle("Test booking");
        referenceBooking.setStartDate(new Date());
        referenceBooking.setEndDate(new Date());
        referenceBooking.setAttendees(10);
        referenceBooking.setRemark("Remark XXXX");
        referenceBooking.setCancelled(true);
        referenceBooking.setRoom(room());

        return referenceBooking;
    }
}

2 个答案:

答案 0 :(得分:4)

您需要先创建对象而不使用递归引用。然后,一旦创建了对象,就可以设置引用这些其他对象的值。因此,您将无法在相同的工厂方法中执行此操作,但稍后在使用这些工厂方法获取对象之后。

public static Room room() { //done
    Room referenceRoom = new Room();
    referenceRoom.setRoomId(100);
    referenceRoom.setRoomIdentifier("Room XXXX");
    referenceRoom.setRoomNumber("Room Number XXX");
    referenceRoom.setDoorPlate("Door Plate XXX");
    referenceRoom.setRoomZone("Room Zone XXX");
    referenceRoom.setBarcode("2345234");
    referenceRoom.setSeats("20 Seats");
    referenceRoom.setStatus(Room.RoomStatus.Available);
    // don't set "foreign keys" yet
    return referenceRoom;
}

// do similar pruning for the other factories

Room room = room();
Location location = location();
room.setLocation(location);
location.setRoom(room);

// create new void methods that wire up the relationships like this

你所拥有的本质上是关系数据,就像在SQL数据库中一样。可能想要研究将RDBMS数据转换为对象的库如何处理外键引用。

答案 1 :(得分:2)

正如评论中已经说明的那样,您的问题不是由于单元测试本身。你只需要进行无限递归调用:

location()调用building()调用location() ...(也许这不是唯一的例子)。

堆栈跟踪是否显示问题的来源?

正如@Novaterata建议的那样,你不应该互相称呼你的“工厂”方法。你应该从外面组装它们。