java - 使用模拟构造函数参数模拟抽象类?

标签 java spring unit-testing mocking mockito

我想使用 Mockito 对抽象类进行单元测试,详见 great answer.

诀窍在于,抽象类依赖于注入(inject)其构造函数的策略。我已经创建了该策略的模拟,并且我希望我的模拟 BaseClass 实例将模拟策略用于我的单元测试。

关于如何连接它有什么建议吗?我目前没有使用任何 IoC 框架,但正在考虑使用 Spring。也许它可以解决问题?

// abstract class to be tested w/ mock instance
abstract BaseClass
{
    // Strategy gets mocked too 
    protected BaseClass( Strategy strategy)
    {
        ...
    }
}

更新:
根据 Mockito 邮件列表,目前没有一种方法可以将参数传递给模拟的构造函数。

最佳答案

我最终只是使用反射在我的基类中设置了一个私有(private)字段,如下所示:

// mock the strategy dependency
Strategy strategyMock = mock( Strategy.class);
when(....).thenReturn(...);

// mock the abstract base class
BaseClass baseMock = mock(BaseClass.class, CALLS_REAL_METHODS);

// get the private streategy field
Field strategyField = baseMock.getClass().getSuperclass().getDeclaredField("_privateStrategy");

// make remove final modifier and make field accessible
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(strategyField, strategyField.getModifiers() & ~Modifier.FINAL);          
strategyField.setAccessible(true);

// set the strategy
strategyField.set(baseMock, strategyMock);

// do unit tests with baseMock
...

如果私有(private)字段的名称发生变化,它就会中断,但它已被注释,我可以接受。这很简单,它是一行代码,我发现这比在我的测试中公开任何 setter 或必须显式子类化更可取。

编辑:所以它不再是一行代码,因为我的私有(private)字段需要是“最终的”,需要一些额外的反射代码才能解决。

关于java - 使用模拟构造函数参数模拟抽象类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10182442/

相关文章:

java - 是否可能与 URLEncoder 发生名称冲突

java - 如何使用 jaxb 从 java 对象创建 xml

objective-c - 你如何在 Xcode 中进行 TDD?

unit-testing - 在 InMemoryDatabase 中模拟 EF 核心计算字段以进行单元测试

angular - 如何在 Angular 单元测试中模拟函数中的服务调用?

java - 当用户在编辑文本中输入金额时,用金额替换 0 的最佳方法

java - 如何将 ArrayList 模型更改为 JSON

java - Spring EntityManager 在方法完成时提交事务

java - 如何杀死 quartz 预定线程?

java - Spring Boot - Spring Boot Starter Actuator 的问题