java - 部分模拟子类的方法使其绕过父类(super class)构造函数

标签 java unit-testing junit mocking jmockit

我试图仅模拟扩展另一个类 (Person) 的类 (Collaborator) 的方法 (getValue)。但是,设置 Expectations block 后,调用此方法时,模拟类的构造函数不会执行 super(...)

以下示例改编自此处显示的代码:http://jmockit.org/tutorial/Mocking.html#partial

问题发生在对象 Collaborator c3 上。最后一个 assert 失败,我预计它会通过。

public class PartialMockingTest
{
   static class Person
   {
      final int id;

      Person() { this.id = -1; }
      Person(int id) { this.id = id; }

      int getId() { return id; }
   }          

   static class Collaborator extends Person
   {
       final int value;

       Collaborator() { value = -1; }
       Collaborator(int value) { this.value = value; }
       Collaborator(int value, int id) { super(id); this.value = value; }

       int getValue() { return value; }
       final boolean simpleOperation(int a, String b, Date c) { return true; }
   }

   @Test
   public void partiallyMockingAClassAndItsInstances()
   {
      final Collaborator anyInstance = new Collaborator();

      new Expectations(Collaborator.class) {{
         anyInstance.getValue(); result = 123;
      }};

      // Not mocked, as no constructor expectations were recorded:
      Collaborator c1 = new Collaborator();
      Collaborator c2 = new Collaborator(150);
      Collaborator c3 = new Collaborator(150, 20); 

      // Mocked, as a matching method expectation was recorded:
      assertEquals(123, c1.getValue());
      assertEquals(123, c2.getValue());
      assertEquals(123, c3.getValue());

      // Not mocked:
      assertTrue(c1.simpleOperation(1, "b", null));
      assertEquals(45, new Collaborator(45).value);
      assertEquals(20, c3.getId()); // java.lang.AssertionError: expected:<20> but was:<-1>
   }

}

我做错了什么吗?这是一个错误吗?

最佳答案

我不太熟悉期望系统的内部结构,但在调试代码后,我意识到在构造对象之前的期望声明与构造函数混淆了' 调用。

这样,如果您在构造之后移动期望,测试应该通过

final Collaborator anyInstance = new Collaborator();

// Not mocked, as no constructor expectations were recorded:
Collaborator c1 = new Collaborator();
Collaborator c2 = new Collaborator(150);
Collaborator c3 = new Collaborator(150, 20);

new Expectations(Collaborator.class) {{
   anyInstance.getValue(); result = 123;
}};

// Mocked, as a matching method expectation was recorded:
assertEquals(123, c1.getValue());
assertEquals(123, c2.getValue());
assertEquals(123, c3.getValue());

// Not mocked:
assertTrue(c1.simpleOperation(1, "b", null));
assertEquals(45, new Collaborator(45).value);
assertEquals(20, c3.getId());  //it works now

关于java - 部分模拟子类的方法使其绕过父类(super class)构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34043379/

相关文章:

unit-testing - Lucene 索引的单元测试

java - Mockito 具有静态类和返回 void 的方法

java - PaintComponent 的事件监听器

java - Java ArrayList 上的重复

java - 使用 -Xlint :deprecation for details 重新编译

java - (声乐代码)需要一些帮助来寻找文本到语音的插件

javascript - 如果它们是只读的,我如何模拟 ES6 导入的模块?

java - 按顺序进行 Junit 自动化测试

c# - ASP.NET MVC FakeItEasy - 模拟 session 在单元测试中不返回正确的值

java - 使用 mockito 检查是否只用特定参数调用了一次方法