如何将EasyMock模拟注入已测试的类私有字段 [英] How to inject EasyMock mock into tested class private field

查看:342
本文介绍了如何将EasyMock模拟注入已测试的类私有字段的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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.

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);
   }
}

我收到失败的信息:

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

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

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

如何解决此问题?

编辑-答案: 纠正双倍的replay.mocked()之后,我发现(是如此简单!)应该使用EasyMock.expectLastCall()

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

推荐答案

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

Your reflection code looks fine.

自从我使用EasyMock已有很长时间了,但是replay不仅应该在测试中每次模拟都被调用一次吗?您打了两次电话.尝试摆脱第一个replay呼叫.

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

在这种情况下,将包含模拟的字段公开是有意义的吗?通常,应该通过构造函数或setter来设置协作者,从而根本不需要反射.

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.

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

EDIT -- based on your updates -- the error indicates setDataType was 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).

这篇关于如何将EasyMock模拟注入已测试的类私有字段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆