简体   繁体   English

如何使用EasyMock模拟另一种方法调用的方法?

[英]How to mock a method which is called by another method using EasyMock?

I need to mock a method inside a void method. 我需要在void方法中模拟一个方法。

Here is my sample code: 这是我的示例代码:

class MyClass {

    public MyClass(Session s, Boolean b1, Boolean b2)

    void myMethod(some paramaters...) {

        // some code
        int count= setSize();
    }

    int setSize() {

        // some calculation....
        return size;
    }

Now in my test class I want to mock setSize() to return my own value say 300 . 现在在我的测试类中,我想模拟setSize()来返回我自己的值300

I did like: 我喜欢:

MyClass mockclass = createNiceMock(MyClass.class);
EasyMock.expect(mockimplyZero.setBatchSize()).andReturn(Integer.valueOf(300));

mockclass.myMethod(parameters....)

when call myMethod , it's not going properly into the method. 当调用myMethod ,它无法正确进入方法。 I think it might be EasyMock is setting default values to the MyClass constructor. 我认为可能是EasyMock正在为MyClass构造函数设置默认值。 How to do the mock correctly? 如何正确地进行模拟?

There are no methods in MyClass except constructor, myMethod and setSize 除了constructor, myMethodsetSize之外, MyClass中没有方法

You can do it using partial mocking. 你可以使用部分模拟来做到这一点。 Here is an example close to your code. 这是一个接近您的代码的示例。

First the tested class. 首先是测试类。 You will need to create a partial mock of it. 您需要创建一个部分模拟它。 getSize should be mocked, but myMethod should since it is the tested method. 应该myMethod getSize ,但是myMethod应该是测试方法。

Also, frequently, you will want to call a constructor to initialize the class correctly (a classical mock won't call any constructor). 此外,通常,您需要调用构造函数来正确初始化类(经典模拟不会调用任何构造函数)。

class MyClass {

  private boolean b1;
  private boolean b2;

  public MyClass(boolean b1, boolean b2) {
    this.b1 = b1;
    this.b2 = b2;
  }

  int myMethod() {
    return getSize();
  }

  int getSize() {
    return 42;
  }

  public boolean getB1() {
    return b1;
  }

  public boolean getB2() {
    return b2;
  }
}

The test will then be the following 然后测试将如下

import org.junit.Test;

import static org.easymock.EasyMock.*;
import static org.junit.Assert.*;

public class MyClassTest {

  @Test
  public void test() {
    // Create a partial mock by calling its constructor
    // and only mocking getSize
    MyClass mock = createMockBuilder(MyClass.class)
        .withConstructor(true, true)
        .addMockedMethod("getSize")
        .createMock();

    // Record that getSize should return 8 (instead of 42)
    expect(mock.getSize()).andReturn(8);

    // All recording done. So put the mock in replay mode
    replay(mock);

    // Then, these assertions are to prove that the partial mock is 
    // actually doing what we expect. This is just to prove my point. Your
    // actual code will verify that myMethod is doing was is expected

    // 1. Verify that the constructor was correctly called
    assertEquals(true, mock.getB1());
    assertEquals(true, mock.getB2());
    // 2. Verify that getSize was indeed mocked 
    assertEquals(8, mock.myMethod());

    // Check everything expected was indeed called
    verify(mock);
  }
}

Job done. 任务完成。 Note that this isn't necessarily a sign of bad design. 请注意,这不一定是糟糕设计的标志。 I frequently use it when testing the Template method pattern . 我经常在测试Template方法模式时使用它。

You should not mock one method while testing another method on the same class. 同一个类上测试另一个方法时,不应该模拟一个方法。 You could theoretically do that (using a Mokito spy for example). 理论上你可以这样做(例如使用Mokito 间谍 )。

In that sense, you are approaching this on a wrong level: you actually should not care which other methods your method under test calls within your class under test. 从这个意义上说,你在错误的层面上接近这个:你实际上不应该关心你的测试方法在你测试的类中调用哪些其他方法。 But if you have to adapt things for testing, then the way to go would be (for example) a method that allows your test code to setup that size field prior invoking mymethod() . 但是如果你必须适应测试的东西,那么前进的方法将是(例如)一种方法,允许你的测试代码在调用mymethod()之前设置该大小字段。

Or: you separate concerns, and move that "size" part into its own class X. And then your class under test could hold an instance of X; 或者:你分开关注点,并将“大小”部分移动到它自己的类X.然后你的测试类可以保存一个X的实例; and that instance could then be mocked. 然后可以嘲笑那个实例。

Long story short: you want to step back and read some tutorials on how to use EasyMock. 简而言之:您想退一步阅读一些有关如何使用EasyMock的教程。 This not something that you can learn by trial and error. 这不是你可以通过反复试验来学习的东西。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM