【问题标题】:Why Mockito is calling real method?为什么 Mockito 调用真正的方法?
【发布时间】:2021-05-06 15:00:47
【问题描述】:

我有一个类 Service 调用单例类的方法。我想模拟一个 saveContract 方法调用。

public class Service {
    public Contract save(Contract contract) {
        Contract result;
        ...
        result = ContractDao.getInstance().saveContract(contract);
        ...
        return result;
    }
}

我这样修改了 Service 类(添加了一个字段和一个构造函数,仅用于测试目的):

public class Service {
    private final ContractDao contractDao;
    
    public Service() {
        this(ContractDao.getInstance());
    }
    
    public Service(final ContractDao contractDao) {
        this.contractDao = contractDao;
    }
    
    public Contract save(Contract contract) {...}
}

我的测试课是:

@ExtendWith(MockitoExtension.class)
class ServiceTest {
    @Mock
    ContractDAO contractDaoMock;
    
    private Service service;
    
    @BeforeEach
    public void setup() {
        service = new Service(contractDaoMock);
    }
    
    @Test
    void saveContractTest() {
        Contract changedContract = new Contract(...);
        when(contractDaoMock.saveContract(any())).thenReturn(changedContract);
    
        Contract givenContract = new Contract(...);
        Contract actualContract = service.save(givenContract);
    
        //Assertions
        ...
    }
}

【问题讨论】:

  • 这能回答你的问题吗? Mocking static methods with Mockito
  • 没有。我没有理由使用 PowerMockito。我按照这里的描述做了:Mocking a singleton with mockito
  • 不,你没有。你从来没有嘲笑过ContractDao.getInstance()
  • 什么意思?
  • @ChrisCross result = ContractDao.getInstance().saveContract(Contract contract); 正在调用您的测试。因此,您应该更改 Service 的实现并使用初始化的 ContractDAO 字段,或者您应该模拟 ContractDao.getInstance()

标签: java junit mockito singleton


【解决方案1】:

添加mockito-inline 依赖并使用MockedStatic 模拟getInstance() 方法。

您的代码应如下所示:

    @Test
    void saveContractTest() {
        Contract changedContract = new Contract(...);
        try (MockedStatic<ContractDAO> mockedContractDAO = mockStatic(ContractDAO.class) {
            mockedContractDAO.when(ContractDAO::getInstance).thenReturn(contractDaoMock);
            when(contractDaoMock.saveContract(any())).thenReturn(changedContract);
    
            Contract givenContract = new Contract(...);
            Contract actualContract = service.save(givenContract);
    
            //Assertions
            ...
        }
    }

查看此处的文档以了解有关模拟静态方法的更多信息:https://javadoc.io/static/org.mockito/mockito-core/3.9.0/org/mockito/Mockito.html#static_mocks

【讨论】:

  • 感谢您的宝贵时间,但我找到了正确的解决方案。
  • 请发布一个答案,这样我们就可以帮助其他人解决同样的问题! :)
【解决方案2】:

Service.save()我没有换行

result = ContractDao.getInstance().saveContract(contract);

带线

result = contractDao.saveContract(contract);

因此,我们需要使用我们模拟的字段实例,而不是 singleton.getInstance()。

【讨论】:

  • 我注意力不集中,犯了那个错误。
猜你喜欢
  • 2021-11-28
  • 1970-01-01
  • 1970-01-01
  • 2023-03-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-24
  • 1970-01-01
相关资源
最近更新 更多