【问题标题】:Grails Fixtures / Build Test Data plugin not working within a Unit TestGrails Fixtures / Build Test Data 插件在单元测试中不起作用
【发布时间】:2013-02-03 09:28:09
【问题描述】:

我正在尝试在服务单元测试中使用Grails Fixtures Plugin。我正在使用 grails 2.2。

我的 BuildConfig.groovy 中有下一个代码

plugins {
    compile ":fixtures:1.2"
    compile ":build-test-data:2.0.3"
    ...
    ..
    .
}

最初我尝试过

@TestFor(HotelService)
@Mock([Place])
class HotelServiceTests {
    def fixtureLoader 

    void testFixturesInUnitTests() {
        def fixture = fixtureLoader.build {
            hotel(Place, name: "Hotel Hilton")
        }
    }
}

上述测试失败:

|  java.lang.NullPointerException: Cannot invoke method build() on null object

通过 Google 搜索,我在 Grails User Mailing List 中发现,fixtureLoader 必须在单元测试中显式创建。

  import grails.plugin.fixtures.*

  @TestFor(HotelService)
    @Mock([Place])
    class HotelServiceTests {
        def fixtureLoader 
        def grailsApplication

        @Before 
        void setUp() {
            fixtureLoader = new FixtureLoader(grailsApplication)
        }

        void testFixturesInUnitTests() {
            def fixture = fixtureLoader.build {
                hotel(Place, name: "Hotel Hilton")
            }
        }
    }

测试失败,出现下一个错误:

 java.lang.NullPointerException: Cannot invoke method hasGrailsPlugin() on null object
    at grails.plugin.fixtures.builder.FixtureBuilder.lookForBuildTestDataPlugin(FixtureBuilder.groovy:53)
    at grails.plugin.fixtures.builder.FixtureBuilder.<init>(FixtureBuilder.groovy:49)
    at grails.plugin.fixtures.Fixture.createBuilder(Fixture.groovy:75)
    at grails.plugin.fixtures.Fixture.build(Fixture.groovy:44)
    at grails.plugin.fixtures.FixtureLoader.build(FixtureLoader.groovy:46)

另一个谷歌搜索,我发现了一个“hack”以避免之前的错误。

 import grails.plugin.fixtures.*
 import org.codehaus.groovy.grails.plugins.GrailsPluginManager
 import org.codehaus.groovy.grails.plugins.PluginManagerHolder

 @TestFor(HotelService)
    @Mock([Place])
    class HotelServiceTests {
        def fixtureLoader 
        def grailsApplication

        @Before 
        void setUp() {
            fixtureLoader = new FixtureLoader(grailsApplication)
            PluginManagerHolder.pluginManager = [hasGrailsPlugin: { String name -> true }] as GrailsPluginManager 
        }

        void testFixturesInUnitTests() {
            def fixture = fixtureLoader.build {
                hotel(Place, name: "Hotel Hilton")
            }
        }
    }

现在我收到下一个错误:

java.lang.NullPointerException: Cannot invoke method isDomainClass() on null object
    at grails.plugin.fixtures.buildtestdata.BuildTestDataBeanDefinitionTranslator.translate(BuildTestDataBeanDefinitionTranslator.groovy:54)
    at grails.plugin.fixtures.buildtestdata.BuildTestDataBeanDefinitionTranslator.translate(BuildTestDataBeanDefinitionTranslator.groovy:43)
    at grails.plugin.fixtures.builder.FixtureBuilder.translateToBuild(FixtureBuilder.groovy:126)
    at grails.plugin.fixtures.builder.FixtureBuilder.invokeMethod(FixtureBuilder.groovy:121)
    at com.softamo.movilrural.TopRuralScraperServiceTests$_testFixturesInUnitTests_closure2.doCall(TopRuralScraperServiceTests.groovy:26)

我不知道如何解决这个问题。任何反馈都非常受欢迎。

【问题讨论】:

    标签: grails fixtures


    【解决方案1】:

    fixtureLoader.build() 方法与Build Test Data plugin 集成。固定装置插件旨在与集成测试结合使用。

    另请参阅此问题http://jira.grails.org/browse/GPFIXTURES-21@TestFor 注释将测试标记为单元,因此您需要将其删除。

    文件/test/integration/com.example/HotelServiceTests.groovy

        class HotelServiceTests extends GroovyTestCase {
            FixtureLoader fixtureLoader
            Fixture fixture
            void setUp() {
                fixture = fixtureLoader.load {
                    build {
                        hotel(Place, name: "Hotel Hilton")
                    }
                }
            }
    
            void testFixturesInUnitTests() {
                // given:
                HotelService service = new HotelService()
                // when:
                List<Place> hotels = service.list()
                // then:
                assert hotels.size() == 1
                assert hotels[0] == fixture.hotel
            }
        }
    

    希望对你有帮助。

    【讨论】:

    • 我是否需要在所有测试中加载夹具?构建方法是同时使用FixturesBuild Test Data 插件的一种方式吗?谢谢
    • 是的,方法 build() 是由 Build Test Data 插件添加的。您可以在测试方法中使用fixtureLoader。另外我想建议你用 (grails.org/plugin/spock)[Spock] 而不是 jUnit. 编写测试
    • 非常感谢。同时使用两者可以节省大量时间。
    【解决方案2】:

    我并不是真正的夹具加载器专家,但您似乎只是调用了错误的方法(build 而不是 load)。

    @TestFor(HotelService)
    @Mock([Place])
    class HotelServiceTests {
        def fixtureLoader 
    
        void testFixturesInUnitTests() {
            def fixture = fixtureLoader.load {
                hotel(Place, name: "Hotel Hilton")
            }
        }
    }
    

    我没试过,但是你可以在这里查看fixture loader的使用:Grails Fixtures Plugin - Reference Documentation

    【讨论】:

    • 之前的方法行不通,因为在单元测试中未绑定fixtureLoader bean,但在集成测试中可以。
    • 正如我在回答中所说的,我没有尝试过,感谢您的报告。 :)
    【解决方案3】:

    实际上并没有办法支持在 Grails 单元测试中使用夹具插件。

    您可以使用 BuildTestData 插件实现相同的目标,该插件提供支持 UnitTests 的 @Build 注解。

    【讨论】:

      猜你喜欢
      • 2013-04-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-16
      相关资源
      最近更新 更多