首页 > 解决方案 > Mockito 没有嘲笑我的 @Autowired 课程

问题描述

我遇到了一个问题,在模拟我的类时,我在模拟对象上得到 NullPointerException,我不明白为什么 mockito 不只模拟一个由@Mock 注释的类。有人知道那里有什么问题吗?

测试类

public class TimeoutJpaTransactionManager extends JpaTransactionManager {

    private final String TRANSACTION_METHOD_NAME= String.join(".", ZapisPakietuReceptService.class.getName(), "transactionMethod");

    @Autowired
    private TransactionTimeoutConfig transactionTimeoutConfig;

    public TimeoutJpaTransactionManager(EntityManagerFactory emf) {
        super(emf);
    }

    protected int determineTimeout(TransactionDefinition definition) {
        if (TRANSACTION_METHOD_NAME.equals(definition.getName())) {
            return transactionTimeoutConfig.getSgr();
        }

        return super.getDefaultTimeout();
    }
}

自动接线类

@Getter
@Setter
@Component
@ConfigurationProperties(prefix = "transaction.timeout")
public class TransactionTimeoutConfig {

    private int sgr;
}

测试类

public class TimeoutJpaTransactionManagerTest {

    @InjectMocks
    private TimeoutJpaTransactionManager timeoutJpaTransactionManager;

    @Mock
    private EntityManagerFactory entityManagerFactory;

    @Mock
    private TransactionDefinition transactionDefinition;

    @Mock
    private TransactionTimeoutConfig transactionTimeoutConfig;

    private final String TRANSACTION_METHOD_NAME_MOCK= String.join(".", ZapisPakietuReceptService.class.getName(), "transactionMethod");
    private final int TIMEOUT_VALUE= 30;

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

    @Test
    public void testDetermineTimeout() {
        //given
        Mockito.when(transactionDefinition.getName()).thenReturn(TRANSACTION_METHOD_NAME_MOCK);
        Mockito.when(transactionTimeoutConfig.getSgr()).thenReturn(TIMEOUT_VALUE);

        //when
        int result = timeoutJpaTransactionManager.determineTimeout(transactionDefinition);

        //then
        Assertions.assertThat(result).isEqualTo(TIMEOUT_VALUE);
    }
}

奇怪的是,我无法理解的是,通过添加另一条这样的行似乎一切正常,并且 TransactionDefinition 真的被嘲笑:

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

标签: springunit-testingspring-bootmockitotestng

解决方案


多亏了 M. Deinum 评论,我才能够弄清楚,似乎问题出在混合字段和构造函数注入上。解决方案是将依赖项移动到构造函数,然后将其连接到那里,或者将当前测试用例修改为

@InjectMocks
    private TimeoutJpaTransactionManager timeoutJpaTransactionManager;

    @Mock
    private TransactionDefinition transactionDefinition;

    @Mock
    private TransactionTimeoutConfig transactionTimeoutConfig;

    private EntityManagerFactory entityManagerFactory;

    private final String TRANSACTION_METHOD_NAME_MOCK= String.join(".", ZapisPakietuReceptService.class.getName(), "transactionMethod");
    private final int TIMEOUT_VALUE= 30;

    @BeforeMethod
    public void setUp() {
        entityManagerFactory = Mockito.mock(EntityManagerFactory.class);
        timeoutJpaTransactionManager = new TimeoutJpaTransactionManager(entityManagerFactory);
        MockitoAnnotations.initMocks(this);
    }

推荐阅读