【问题标题】:Mockito: inject a class mock into a private interface fieldMockito:将类模拟注入私有接口字段
【发布时间】:2014-09-26 23:09:13
【问题描述】:

我正在使用 Mockito 1.9.5 进行一些单元测试。我正在尝试将一个具体的类模拟注入一个具有私有接口字段的类中。这是一个例子:

我正在测试的课程

@Component
public class Service {

    @Autowired 
    private iHelper helper;

    public void doSomething() {
        helper.helpMeOut();
    }
}

我对这门课的测试

@RunWith(MockitoJUnitRunner.class)
public class ServiceTest {

    @Mock
    private iHelper helper;

    @InjectMocks
    private Service service;

    @Before
    public void setup() {
        service = new Service();
    }

    @Test
    public void testStuff() {
        doNothing().when(helper).helpMeOut();
        service.doSomething();
    }
}

当尝试在 doSomething() 中调用 helper.helpMeOut() 时,此代码会引发 NullPointerException。我调试并发现运行测试时 helper 为空。我还尝试将 iHelper 更改为具体的类 Helper,并且发生了同样的问题。

有什么建议吗?如何让 Mockito 正确地将模拟注入接口私有字段?

【问题讨论】:

  • 您所做的完全正确。这应该有效。事实上,它对我有用;我经常使用这种方法。如果您希望真正的 Mockito 专家看到它,您可以尝试将其发布到 Mockito 用户列表。
  • 为什么不将helperfield 可见性更改为默认值?我猜该服务与其测试在同一个包中。
  • @ponomandr 这无济于事。 @InjectMocks 代码有一些反射魔法,可以设置私有字段。
  • service 怎么样?它是否被实例化了?虽然不太可能,但您的 IDE/控制台可能没有选择 mockito 的运行器。
  • 抱歉,我忘记在实例化服务的地方添加 @Before 方法。我已经编辑了代码以反映这一点。

标签: java mockito


【解决方案1】:

@acdcjunior 的评论帮助我找出了问题所在。使用 new 关键字实例化服务导致 Spring 无法正确注入依赖项(在本例中为 helper)。我通过在测试中的服务中自动装配来解决这个问题。我的最终工作代码如下所示:

我正在测试的课程

@Component
public class Service {

    @Autowired 
    private iHelper helper;

    public void doSomething() {
        helper.helpMeOut();
    }
}

我对这门课的测试

@RunWith(MockitoJUnitRunner.class)
public class ServiceTest {

    @Mock
    private iHelper helper;

    @InjectMocks
    @Autowired
    private Service service;

    @Test
    public void testStuff() {
        doNothing().when(helper).helpMeOut();
        service.doSomething();
    }
}

希望这对其他人有所帮助。感谢您的建议!

【讨论】:

  • 如果我没有 spring 应用程序该怎么办。我有一个简单的 java SE 应用程序。我怎样才能得到@Autowired
【解决方案2】:

根据the docs,您缺少设置。

@Before
public void initMocks() {
    MockitoAnnotations.initMocks(this);
}

已编辑*

看看这个页面why you should not use @InjectMock to autowire fields

【讨论】:

  • 其实,如果我使用@RunWith(MockitoJUnitRunner.class) 注解,这不是必须的:docs.mockito.googlecode.com/hg/1.9.5/org/mockito/runners/…
  • 正如@zongweil 所说,如果您使用 @RunWith(MockitoJUnitRunner.class) ,那么会为您调用 initMocks。所以这个答案是不正确的。
  • 你是对的,对不起。然后我发现了。希望它有效!
  • 如果你使用TestNG,这实际上是正确的答案
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-22
  • 1970-01-01
  • 1970-01-01
  • 2017-10-11
相关资源
最近更新 更多