DbUnit Assertion числа с плавающей запятой

Я тестирую свой слой DAO с помощью DbUnit. Я предварительно заполняю базу данных из набора данных XML, выполняю некоторые действия, а затем утверждаю против известного результата.

Assertion.assertEquals(expectedDataSet, actualDataSet);

Набор данных содержит столбец с числом с плавающей запятой. Затем сравнивая эти столбцы, я получаю:

junit.framework.ComparisonFailure: value (table=OrderLine_T, row=2, col=price) expected:<2.99[]> but was:<2.99[0000009536743]>.

Значения равны, но поскольку числа с плавающей запятой не могут быть точно представлены в двоичной форме, утверждение не выполняется. В JUnit у нас есть assertEquals(double expected, double actual, double delta). Как нам установить некоторую дельту в DbUnit для сравнения чисел с плавающей запятой?

Исходный набор данных:

<dataset>
    <Customer_T id="1" name="Anthony"/>
    <Customer_T id="2" name="John"/>

    <Order_T id="1" date="2012-06-07 14:30" customer_id="1" />
    <Order_T id="2" date="2012-06-07 15:31" customer_id="2" />

    <OrderLine_T id="1" order_id="1" product_id="1" price="2.99" quantity="5" />
    <OrderLine_T id="2" order_id="2" product_id="2" price="3.49" quantity="10" />
</dataset>

Ожидаемый результат:

<dataset>
    <Customer_T id="1" name="Anthony"/>
    <Customer_T id="2" name="John"/>

    <Order_T id="1" date="2012-06-07 14:30" customer_id="1" />
    <Order_T id="2" date="2012-06-07 15:31" customer_id="2" />

    <OrderLine_T id="1" order_id="1" product_id="1" price="2.99" quantity="5" />
    <OrderLine_T id="2" order_id="2" product_id="2" price="3.49" quantity="10" />

<!--     Below added -->
    <Order_T id="3" date="1987-06-07 9:15:10" customer_id="2" />
    <OrderLine_T id="3" order_id="3" product_id="1" price="2.99" quantity="2" />
    <OrderLine_T id="4" order_id="3" product_id="5" price="3.55" quantity="8" />
</dataset>

Код:

/* Should save order correctly (including order lines) */
    @Test
    public void save() throws Exception {
        /* Create new order */
        Set<OrderLine> lines = new HashSet<OrderLine>();
        lines.add(new OrderLine(1, (float)2.99, 2));
        lines.add(new OrderLine(5, (float)3.55, 8));

        Calendar cal = Calendar.getInstance();
        cal.set(1987, 6, 7, 9, 15, 10);
        Date date = cal.getTime();

        Customer customer = customerDAO.findById(2); // John

        Order order = new Order(date, lines, customer);
        orderDAO.save(order);
        entityManager.flush();

        /* Assert order is saved */
        IDataSet expectedDataSet = new FlatXmlDataSetBuilder().build(Thread.currentThread()
                                                                           .getContextClassLoader()
                                                                           .getResourceAsStream("data-set-afterAddOrder.xml"));
        IDataSet actualDataSet = getDatabaseConnection().createDataSet();

        Assertion.assertEquals(expectedDataSet, actualDataSet);
    }

Редактировать:

Наверное, нужно упомянуть, что я использую в памяти HSQLDB. Просто попробовал MySQL, и все прошло успешно.

Пробовал установить ToleratedDelta безуспешно:

IDatabaseConnection connection = new DatabaseConnection(((SessionImpl) (entityManager.getDelegate())).connection());
HsqldbDataTypeFactory dataTypeFactory = new HsqldbDataTypeFactory();
dataTypeFactory.addToleratedDelta(new ToleratedDelta("OrderLine_T", "price", 0.01));
connection.getConfig().setProperty(DatabaseConfig.PROPERTY_DATATYPE_FACTORY, dataTypeFactory);

Edit2:

Я использовал hibernate.hbm2ddl.auto = create, чтобы экспортировать схему в базу данных. Получив идею от fredt, я изменил тип поля price в моей сущности на BigDecimal и добавил дополнительные параметры точности и масштаба столбца:

@Column(precision=10, scale=4)
private BigDecimal price;

Это переводится на PRICE NUMERIC(10,4). Проблема решена благодаря fredt.


person Robertas    schedule 15.08.2012    source источник
comment
Чтобы избежать этого, вы можете определить свой столбец как DECIMAL или NUMERIC с требуемой точностью и масштабом.   -  person fredt    schedule 15.08.2012
comment
@fredt Спасибо. Изменил HSQLDB с mem на файл, указал столбец как PRICE DECIMAL (10,2), и он работает. Если вы повторно напишете свой комментарий, чтобы ответить, я с радостью его приму.   -  person Robertas    schedule 15.08.2012


Ответы (1)


Если столбец определен как DECIMAL или NUMERIC с требуемой точностью и масштабом, значение будет иметь точное количество цифр после десятичной точки, и проблемы можно избежать.

person fredt    schedule 15.08.2012