java 如何将 EasyMock 模拟注入测试类私有字段

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10011480/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 23:15:14  来源:igfitidea点击:

How to inject EasyMock mock into tested class private field

javareflectionjuniteasymock

提问by Marcin

I'm using EasyMock to create mock that is one of private parameters (without setter) in tested class. I tried using reflection - but it does not work correctly.

我正在使用 EasyMock 创建模拟,它是测试类中的私有参数(没有设置器)之一。我尝试使用反射 - 但它不能正常工作。

public class TestedClassTest{
    @Test
    public void test(){
      TestedClass instance = new TestedClass();
      MockedClass mocked = EasyMock.createMock(MockedClass.class);
      Data data = new Data();

      //Void setter
      DataType dataType = (myDataType.DataType) EasyMock.anyObject();
      mocked.setDataType(dataType);
      EasyMock.expectLastCall();

      //expect
      EasyMock.expect(mocked.getData()).andReturn(data);
      EasyMock.replay(mocked);

      Field field = instance.getClass().getDeclaredField("mockedClass")
      field.setAccessible(true);
      field.set(instance, mocked);

      //run tested method
      instance.someAction();

      EasyMock.verify(mocked);
   }
}

Im getting FAILED info:

我收到失败的信息:

Unexpected method call MockedClass.setDataType(myData.MyData@104306d75):
MockedClass.getData(): expected: 1, actual: 0
junit.framework.AssertionFailedError: 
Unexpected method call MockedClass.setDataType(myData.MyData@132006d75):
MockedClass.getData(): expected: 1, actual: 0

Im sure this method is fired on "MockedClass" object during tested "instance.someAction()"

我确定在测试“instance.someAction()”期间在“MockedClass”对象上触发了此方法

How to resolve this problem?

如何解决这个问题?

Edited - Answer : After correcting doubled replay.mocked()I found (so simple!) that one more void method should be declared using EasyMock.expectLastCall()

编辑 - 答案:更正后replay.mocked()我发现(如此简单!)应该使用声明另一个无效方法 EasyMock.expectLastCall()

采纳答案by hvgotcodes

Your reflection code looks fine.

您的反射代码看起来不错。

It's been a long time since I've used EasyMock, but isn't replayonly supposed to be called once per mock in a test? You are calling it twice. Try getting rid of the first replaycall.

我已经很长时间没有使用 EasyMock 了,但是replay在测试中每个模拟不应该只调用一次吗?你叫它两次。尝试摆脱第一个replay电话。

In this case, does it make sense to have the field that contains the mock be public? In general, collaborators should be set via either constructor or setter, eliminating the need for reflection at all.

在这种情况下,将包含模拟的字段设为公开是否有意义?一般来说,合作者应该通过构造函数或设置器设置,完全不需要反射。

EDIT -- based on your updates -- the error indicates setDataTypewas called on the mock, but the mock did not expect it to be called. Perhaps your class is calling it twice, perhaps it is being called out of order, or calling it with an argument you didn't expect (although I would expect the error to be different in this case).

编辑——根据你的更新——错误表明setDataType在模拟上被调用,但模拟不希望它被调用。也许你的班级调用了它两次,也许它被无序调用,或者用你没想到的参数调用它(尽管我希望在这种情况下错误会有所不同)。