首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何对使用AlienFactory的afIoc和afMorphia框架的扇汤姆DAO类进行单元测试?

如何对使用AlienFactory的afIoc和afMorphia框架的扇汤姆DAO类进行单元测试?
EN

Stack Overflow用户
提问于 2015-01-07 21:43:30
回答 1查看 103关注 0票数 1

假设我有一个简单的扇汤姆应用程序从MongoDB数据库中检索数据。该应用程序使用afIoc (AlienFactory的IoC框架)和afMorphia (AlienFactory的MongoDB框架)。我有一个名为Foo的简单实体和一个DAO类(FooDao),用于从数据库中检索Foo实体。我想使用fant命令测试DAO类,但下面是错误信息。我做错了什么,还是有更好的方法来写考试?请注意,此应用程序不使用afBedSheet web框架。

代码语言:javascript
复制
TEST FAILED
afIoc::IocErr: No dependency matches type sys::Type.
Ioc Operation Trace:
  [ 1] Injecting dependencies into fields of testAfIoc::FooDaoTest
  [ 2] Injecting dependencies into fields of testAfIoc::FooDaoTest
  [ 3] Looking for dependency of type testAfIoc::FooDao?
  [ 4] Creating REAL Service 'testAfIoc::FooDao'
  [ 5] Creating 'testAfIoc::FooDao' via ctor autobuild
  [ 6] Injecting dependencies into fields of testAfIoc::FooDao
  [ 7] Looking for dependency of type afMorphia::Datastore?
  [ 8] Creating REAL Service 'afMorphia::Datastore'
  [ 9] Creating 'afMorphia::Datastore' via ctor autobuild
  [10] Determining injection parameters for afMorphia::DatastoreImpl sys::Void make(sys::Type type, afMongo::Database database, |sys::This->sys::Void| in)
Stack Trace:
  afIoc::Utils.stackTraceFilter (Utils.fan:50)
  afIoc::RegistryImpl.injectIntoFields (RegistryImpl.fan:253)
  testAfIoc::FooDaoTest.setup (FooDaoTest.fan:17)
  java.lang.reflect.Method.invoke (Method.java:483)
  fan.sys.Method.invoke (Method.java:559)
  fan.sys.Method$MethodFunc.callList (Method.java:204)
  fan.sys.Method.callList (Method.java:138)
  fanx.tools.Fant.runTest (Fant.java:190)
  fanx.tools.Fant.test (Fant.java:110)
  fanx.tools.Fant.test (Fant.java:32)
  fanx.tools.Fant.run (Fant.java:284)
  fanx.tools.Fant.main (Fant.java:327)

Time: 377ms

Failed:
  testAfIoc::FooDaoTest.testFindAll

***
*** 1 FAILURES [1 tests, 0 methods, 0 verifies]
***

这就是我的类的样子(显式“使用”语句来显示哪些类来自于范汤姆荚):

扇/AppModule.fan

代码语言:javascript
复制
using afIoc::Configuration
using afIoc::Contribute
using afIoc::ServiceDefinitions
using afIocConfig::ApplicationDefaults
using afMorphia::MorphiaConfigIds
using afMorphia::Datastore

class AppModule {

  @Contribute { serviceType=ApplicationDefaults# }
  static Void contributeAppDefaults(Configuration config) {
    config[MorphiaConfigIds.mongoUrl] = `mongodb://localhost:27017/foo`
  }

  static Void defineServices(ServiceDefinitions defs) {
    defs.add(FooDao#)
    defs.add(Datastore#)
  }

}

扇/扇

代码语言:javascript
复制
using afMorphia::Entity
using afMorphia::Property
using afBson::ObjectId

@Serializable
@Entity { name="foo" }
class Foo {

  @Property const ObjectId _id
  @Property const Str text

  new make(|This| f) { f(this) }
}

扇/福道范

代码语言:javascript
复制
using afIoc::Inject
using afMorphia::Datastore

class FooDao {

  @Inject { type=Foo# }
  Datastore? datastore

  Foo[] all() {
    (Foo[]) datastore.findAll
  }
}

扇/fooDaoTest.fan

代码语言:javascript
复制
using afIoc::Inject
using afIoc::RegistryBuilder
using afIocConfig::ConfigModule
using afMorphia::Datastore

class FooDaoTest : Test {

  @Inject
  FooDao? subject

  override Void setup() {
    registry := RegistryBuilder().addModules([
      AppModule#
      ,ConfigModule#
      ,Datastore#
    ]).build.startup
    registry.injectIntoFields(this)
  }

  Void testFindAll() {
    verifyEq ( subject.all.size, 2 )
  }
}

build.fan

代码语言:javascript
复制
#! /usr/bin/env fan

using build

class Build : BuildPod {

  new make() {
    podName = "testAfIoc"
    summary = "Testing AF IoC"
    version = Version("0.0.1")
    depends = [
      "sys 1.0+",
      "afIoc 2.0.2+",
      "afIocConfig 1.0.16+",
      "util 1.0+",
      "afMongo 1.0.0+",
      "afBson 1.0.0+",
      "concurrent 1.0.8+",
      "afMorphia 1.0.2+"
    ]
    srcDirs = [
      `fan/`,
    ]
    meta = [
      "proj.name" : "Testing Alien Factory IoC framework",
      "afIoc.module" : "testAfIoc::AppModule",
      "org.name" : "Foo",
      "org.uri"  : "http://www.example.com/"
    ]
  }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-01-08 03:05:24

一切都是正确的,您测试DAO的方式也是正确的。(顺便说一句,Foo不需要成为@Serializable .)

问题在于您在哪里构建Registry。因为IoC是一个库,所以您需要向注册表中添加Morphia的模块。还请注意,Datastore不是一个模块,不应该添加:

在fan/FooDaoTest.fan

代码语言:javascript
复制
using afIoc::Inject
using afIoc::RegistryBuilder
using afIocConfig::ConfigModule
using afMorphia::MorphiaModule

class FooDaoTest : Test {

  @Inject
  FooDao? subject

  override Void setup() {
    registry := RegistryBuilder()
      .addModule(AppModule#)
      .addModulesFromPod("afMorphia")
      .addModulesFromPod("afIocConfig")
      .build.startup
    registry.injectIntoFields(this)
  }

  Void testFindAll() {
    verifyEq ( subject.all.size, 2 )
  }
}

在构建自己的Registry时,请确保添加了所有相关的IoC模块和库。

我很惊讶代码没有抛出一个'Datastore' Service Not Found Err (这更能说明问题)--我会看看.

编辑:

啊,是的。在您的AppModule中,不需要将Datastore添加为服务。所有库都应该在它们的模块中定义它们自己的服务,所以您需要做的就是添加这个模块(或者配置一些服务)。

( Datastore有一个特殊的依赖关系提供程序来构建实例,这就是为什么将它作为普通服务添加时不能工作的原因。)

Datastore中删除AppModule定义并重新运行损坏的测试将提供如下结果:

代码语言:javascript
复制
TEST FAILED
afIoc::IocErr: No service matches type afMorphia::Datastore?.

这是(一点)更多的信息和我所期望的。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27829173

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档