如何在def之外添加地图条目

时间:2014-09-11 21:27:01

标签: unit-testing groovy

我正在编写groovy单元测试并使用Map强制,我试图弄清楚如何使用地图定义模拟,但后来在测试中我想在def之外添加一个方法声明。这可能吗?

考虑以下课程。

class MapMockedClass{
   String aMethod() {
      return "original A method";
   }
   String bMethod( String str ) {
      return "original B method with parameter ${str}";
   }
}

我希望这些测试通过。请参阅test_Map_AddC,这是我无法弄清楚的。

  void test_Map_Original() {
     def mock = new MapMockedClass()
     assertEquals( "original A method", mock.aMethod() );
     assertEquals( "original B method with parameter test", mock.bMethod("test") );
  }
  void test_Map_OverrideA() {
     def mock =  [ aMethod: "new A method" ] as MapMockedClass
     assertEquals( "new A method", mock.aMethod() );
     assertEquals( "original B method with parameter test", mock.bMethod("test") );
  }
  void test_Map_OverrideB() {
     def mock =  [ aMethod: "new A method",
                   bMethod: { param -> return "new B method with parameter ${param}" as String }] as MapMockedClass
     assertEquals( "new A method", mock.aMethod() );
     assertEquals( "new B method with parameter test", mock.bMethod("test") );
  }
  void test_Map_AddC() {
     def mock =  [ aMethod: "new A method",
        bMethod: { param -> return "new B method with parameter ${param}" as String }] as MapMockedClass
     assertEquals( "new A method", mock.aMethod() );
     assertEquals( "new B method with parameter test", mock.bMethod("test") );
     // Here I want to add a cMethod to the mock, but its not clear how to do it outside of the definition.
     //mock.inject( cMethod, { return "new C method" });
     //mock[ cMethod ] = { return "new C method" };
     //mock[ 'cMethod' ] = { return "new C method" };
     assertEquals( "new C method", mock.cMethod("test") );
 } 

以下是发布答案后的新工作方法。

void test_Map_AddC() {
  def mock =  [ aMethod: "new A method",
        bMethod: { param -> return "new B method with parameter ${param}" as String }] as MapMockedClass
  assertEquals( "new A method", mock.aMethod() );
  assertEquals( "new B method with parameter test", mock.bMethod("test") );
  // Here I want to add a cMethod to the mock, but its not clear how to do it outside of the definition.
  mock.metaClass.cMethod = { return "new C method" };
  assertEquals( "new C method", mock.cMethod("test") );
}
void test_Map_ModifyAandB() {
  def mock =  [ aMethod: "new A method",
        bMethod: { param -> return "new B method with parameter ${param}" as String }] as MapMockedClass
  assertEquals( "new B method with parameter test", mock.bMethod("test") );

  // http://otherthanthink.blogspot.com/2012/08/how-to-override-groovy-instance-and.html
  mock.metaClass.aMethod = { return "An override for method a" }
  assertEquals( "An override for method a", mock.aMethod() );

  // Make sure you declare the String here otherwise it can't find the method.
  mock.metaClass.bMethod = { String param -> return "second B method with parameter ${param}" as String  };
  assertEquals( "second B method with parameter foo", mock.bMethod("foo") );
}

1 个答案:

答案 0 :(得分:2)

cMethod必须添加到metaClass的{​​{1}}。

MapMockedClass

在断言之前应该使用上面一行。