【问题标题】:Grails UnitTest Ensure BigDecimal not a stringGrails UnitTest 确保 BigDecimal 不是字符串
【发布时间】:2014-09-30 21:56:31
【问题描述】:

系统: Java 1.7 Grails 2.2

在我的域对象中:

class Timer{

    BigDecimal hours

    static constraints = {
        hours min: 0.5, validator: { h ->
            // The hours has to be a number in whole or half hour increments.

               System.out.println "h:" + h.toString()

            // Twice the number :
            def h2 = 2 * h

            // Extract h2 fractional portion:
            String numberStr = Double.toString(h2);
            String fractionalStr = numberStr.substring(numberStr.indexOf('.') + 1);
            int fractional = Integer.valueOf(fractionalStr);

            System.out.println "fraction:" + fractional

            // if the fraction is 0 then "h" is a multiple of 0.5
            // ie: h = 1.5 => h2 = 3.0, fractional = 0  return TRUE
            // ie: h = 1.1 => h2 = 2.2, fractional = 2  return FALSE
            (fractional == 0)
        }
    }
}

在单元测试中

@Build(Timer)
class TimerTests {


    @Before
    void setUp() {

        // Ensure we can invoke validate() on our domain object.
        mockForConstraintsTests(Timer)
    }

    /**
     * Ensure setup creates a valid instance
     */
    void testValid() {
        Timer t = Timer.build()
        assertTrue t.validate()
    }


    /**
     * hours must be a number
     */
    void testHours(){
        Timer m = Timer.build()
        assertTrue m.validate()



        t.hours = 1;
        assertTrue m.validate()

        t.hours = 1.5;
        assertTrue m.validate()

        t.hours = 1.3;
        assertFalse m.validate()
        assertEquals 'validator', t.errors['hours']

        // Test Min constraint
        t.hours = 0;
        assertFalse t.validate()
        assertEquals 'min', t.errors['hours']


        //
        // Test non numbers
        t = new Timer()
        t.hours = "ss"
        assertFalse t.validate()
    }
}

我收到错误 org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object 'ss' with class 'java.lang.String' to class 'java.math.BigDecimal'

我想确保不能输入字符串,并且小时字段以整小时或半小时为增量。

欢迎提出任何建议。

谢谢

【问题讨论】:

  • 您的测试表明它不能是字符串。您需要更改您的代码以期望出现异常。

标签: java grails groovy


【解决方案1】:

问题如下:

t.hours = "ss"

您正在将 String 值分配给 BigDecimal 类型的属性。

如果您让数据绑定系统执行分配,那么您可以通过直接为属性分配值来利用您正在规避的一系列功能。

以下测试将通过(为简单起见,我将 .build() 排除在外):

package demo

import grails.test.mixin.*
import org.junit.*

@TestFor(Timer)
class TimerTests {

    @Before
    void setUp() {
        // Ensure we can invoke validate() on our domain object.
        mockForConstraintsTests(Timer)
    }

    void testHours(){
        Timer m = new Timer(hours: 1)
        assertTrue m.validate()

        m.hours = 1.5;
        assertTrue m.validate()

        m.hours = 1.3;
        assertFalse m.validate()
        assertEquals 'validator', m.errors['hours']

        // Test Min constraint
        m.hours = 0;
        assertFalse m.validate()
        assertEquals 'min', m.errors['hours']

        // Test non numbers
        m = new Timer(hours: 'ss')
        assertFalse m.validate()
    }
}

希望对你有帮助。

【讨论】:

  • 原始问题未指定使用的是哪个 2.2.x 版本。我用 Grails 2.2.5 进行了测试。
  • 测试没有解决这个问题,但最后一次调用 .validate() 应该返回 false,因为 hours 为空。由于类型转换错误,hours 将为 null。如果在调用.validate()之前询问m.errors,应该会出现绑定错误。
  • 哇,这是一个快速而奇妙的反应。它完美地工作。你也是正确的 assertEquals 'nullable', m.errors['hours'] 应该是最后一行而不是我写的。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-17
  • 2018-11-29
  • 2022-01-23
  • 1970-01-01
相关资源
最近更新 更多