Java Mockito 模拟对象返回 null

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16570029/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-16 07:28:57  来源:igfitidea点击:

Mockito mock objects returns null

javatestingjunitmockito

提问by flo8433

I try to implement some tests for my JSF application and for the mocks I am using mockito. (I also use spring)

我尝试为我的 JSF 应用程序和我使用 mockito 的模拟实现一些测试。(我也用弹簧)

@RunWith(MockitoJUnitRunner.class)
public class GeneralConfigServiceImplTest  {

    private GeneralConfigService generalConfigService;

    @Mock
    private GeneralConfigDAO generalConfigDAO;

    @Mock
    private GeneralConfig gen;

    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);
        generalConfigService = new GeneralConfigService();
        ReflectionTestUtils.setField(generalConfigService, "generalConfigDAO", generalConfigDAO);                  
    }

    @Test
    public void testAddGeneralConfigCallDAOSuccess() throws DAOException, EntityNullException, IllegalEntityArgumentException, ParseException, EntityPersistException {
        gen = createGeneralConfigs("label", "value");

        generalConfigService.setInstance(gen);
        generalConfigService.persist();
        log.info(generalConfigService.getInstance().toString());
    }
}

The test succeeds, but when I want to retrieve the instance with the getInstancemethod. All Parameters which I have set before (via the constructor before) are null. I am new to mocked objects, so is this behavior normal, or is there a mistake in my code?

测试成功,但是当我想用该getInstance方法检索实例时。我之前设置的所有参数(通过之前的构造函数)都是空的。我是模拟对象的新手,所以这种行为是正常的,还是我的代码中有错误?

采纳答案by hoaz

It really depends on GeneralConfigService#getInstance() implementation. Also you can simplify your test code a lot if you use @InjectMocksannotation.

这真的取决于 GeneralConfigService#getInstance() 实现。如果您使用@InjectMocks注释,您也可以大大简化您的测试代码。

When using MockitoJUnitRunneryou don't need to initialize mocks and inject your dependencies manually:

使用时,MockitoJUnitRunner您无需初始化模拟并手动注入您的依赖项:

@RunWith(MockitoJUnitRunner.class)
public class GeneralConfigServiceImplTest  {

    @InjectMocks
    private GeneralConfigService generalConfigService;

    @Mock
    private GeneralConfigDAO generalConfigDAO;

    @Test
    public void testAddGeneralConfigCallDAOSuccess() {
       // generalConfigService is already instantiated and populated with dependencies here
       ...
    }
}

回答by John B

All method calls to Mockitomocks return null by default. If you want it to return something else you need to tell it to do so via a whenstatement.

Mockito默认情况下,所有对模拟的方法调用都返回 null。如果您希望它返回其他内容,则需要通过when语句告诉它这样做。

It seems the you are thinking that the following will work... you call setInstanceand then expect getInstanceto return the value that was passed to setInstancesince this is how the DAO would work. If this is what you are attempting, you shouldn't test setInstanceby then calling getInstancesince getInstancewill return whatever you have configured the mock to return and will have no relation to what was passed to setInstance. Instead, use verifyto validate that the appropriate method of the DAOwas called from the setInstancemethod.

您似乎认为以下内容会起作用……您调用setInstance然后期望getInstance返回传递给的值,setInstance因为这就是 DAO 的工作方式。如果这是您正在尝试的内容,那么您不应该setInstance在调用之前进行测试,getInstance因为getInstance它将返回您配置模拟返回的任何内容,并且与传递给setInstance. 相反,用于verify验证DAOsetInstance方法中调用了 的适当方法。

For example, if GeneralConfigService.setInstancecalls GeneralConfigDAO.setInstancethen your test should look like this...

例如,如果GeneralConfigService.setInstance调用,GeneralConfigDAO.setInstance那么您的测试应如下所示...

@Test
public void testAddGeneralConfigCallDAOSuccess() throws DAOException, EntityNullException, IllegalEntityArgumentException, ParseException, EntityPersistException {
    gen = createGeneralConfigs("label", "value");

    generalConfigService.setInstance(gen);
    generalConfigService.persist();

    verify(genConfigDAO).setInstance(sameInstance(gen));
}

Also, if genis a mock (via @Mock) why are you assigning it to something else via gen = createGeneralConfigs...

另外,如果gen是模拟(via @Mock),为什么要通过gen = createGeneralConfigs...

回答by Swarit Agarwal

Don't forget to use

不要忘记使用

MockitoAnnotations.initMocks(this);

If you are Mocking object through annotation i.e. @Mock Objectname

如果您是通过注释模拟对象,即 @Mock Objectname

回答by FabianoLothor

My problem here was the incorrect import for Testanotation:

我的问题是Test注释导入不正确:

Was

曾是

import org.junit.jupiter.api.Test;

import org.junit.jupiter.api.Test;

Correct

正确的

import org.junit.Test;

import org.junit.Test;