【问题标题】:UnExpected Method Call Assertion Error意外的方法调用断言错误
【发布时间】:2013-12-27 12:25:49
【问题描述】:

我是 EasyMock 的新手,正在努力解决运行测试用例时遇到的以下问题。单元测试因“意外方法调用执行”而失败。首先这是我的应用程序代码:

class Filter {

Filter(FilterExecutor f) {
   filter = f;
}
static FilterExecutor filter;

void handle() {

   filter.execute(object);
}
//some logic here
};

class FilterExtension extends Filter {

FilterExtension(FilterExecutor f) {
   super(f);
}
void handle() {
   //some logic here
   super.handle();
}
} 

测试用例:

class Tests {

FilterExecutor f;
@Override
public void Tests() {
  f=EasyMock.createMock(FilterExecutor.class);
}
@Test
public void test1 {

  EasyMock.expect(f.execute(object)).andReturn(Obj1);
  EasyMock.replay(f);
  FilterExtension test = new FilterExtension(f);
  test.handle();
  //Assert
}

@Test
public void test2 {

  //More or less similar to above
  EasyMock.expect(f.execute(object)).andReturn(Obj1);
  EasyMock.replay(f);
  FilterExtension test = new FilterExtension(f);
  test.handle();
}
} 

如果上述测试用例单独运行,则测试成功通过。如果它们一起运行,则其中一个测试通过,另一个给出断言错误“”UnExpected Method Call execute”。而且如果我在一个测试用例的末尾添加“Filter.filter = null”,那么两个测试用例都是成功了。有人可以解释一下为什么会观察到这种行为吗?

【问题讨论】:

    标签: easymock


    【解决方案1】:

    我在这里看到了 2 个问题:

    1. 依赖项被声明为静态,但随后在构造函数中从参数初始化。
    2. 传递给execute(object) 方法的对象未传递给handle() 方法。

    问题 1 是一个设计问题。如果您想在每次创建新的Filter(或FilterExetnsion)时初始化FilterExecutor,那么为什么不将其设为实例变量呢?它显然与类的特定实例有内在联系,而不是类本身。

    问题 2 可能是设计问题,或者可能与测试中的期望有关。在方法调用test.handle() 中调用filter.execute(object)。但是,您的测试类不提供传递给execute 的对象。这意味着在 filter.execute(object) 中传递的对象与您在 EasyMock.expect(f.execute(object)).andReturn(Obj1); 中告诉它的对象不同

    有两种方法可以解决这个问题:

    • A) 改变您对使用 Capture 的期望。
    • B) 更改您的 handle 方法以接收对象,然后将其提供给您测试中的 handle 方法调用。

    对于选项 A,See this good Stack Overflow post

    我认为测试方法看起来有点像这样:

    @Test
    public void test1() {
        final Capture<Object> object = new Capture<Object>();
        EasyMock.expect(this.mockFilterExecutor.execute(EasyMock.capture(object))).andReturn(new Object());
        EasyMock.replay(this.mockFilterExecutor);
        final FilterExtension test = new FilterExtension(this.mockFilterExecutor);
        test.handle();
    
        final Object capturedObject = object.getValue();
        //Assert
    }
    

    对于选项 B,您可以执行以下操作,但显然,如果您提供给 execute() 的对象无法从 handle() 方法之外构造或接收,这将不可行

    Filter 类中的句柄方法如下所示:

    public void handle(final Object object) {
        this.filter.execute(object);
    }
    

    FilterExtension 类中的句柄方法如下所示:

    @Override
    public void handle(final Object object) {
        super.handle(object);
    }
    

    您的测试将如下所示:

    @Test
    public void test1() {
        final Object object = new Object();
        EasyMock.expect(this.mockFilterExecutor.execute(object)).andReturn(object);
        EasyMock.replay(this.mockFilterExecutor);
        final FilterExtension test = new FilterExtension(this.mockFilterExecutor);
        test.handle(object);
        //Assert
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-04
      • 1970-01-01
      • 1970-01-01
      • 2015-12-25
      相关资源
      最近更新 更多