Spring的JpaRepository save()方法无法使用Mockito进行模拟测试

18

我是Mockito库的新手,卡在某个地方。

问题是当我模拟Spring jpaRepository的save方法时,总是得到null。我在我的项目中使用了这样的代码,但是为了测试,我编写了一个虚拟代码。这是我的代码:

// This is the class for which I am making test case
    @Service("deviceManagementService")
    @Scope(BRASSConstants.SCOPE_SESSION)
    @Transactional
    public class DeviceManagementServiceImpl implements DeviceManagementService {

        public String  show(){
            Device device = new Device() ;
            device.setContactName("abc");
            Device deviceEntity = deviceDao.save(device);
            System.out.println(deviceEntity);  // i get this null always Why ???
            return "demo";
        }
    }

我正在编写的测试用例是:

    @RunWith(MockitoJUnitRunner.class)
    public class DemoTest {

        @InjectMocks
        private DeviceManagementServiceImpl deviceManagementServiceImpl;

        @Mock
        private DeviceDao deviceDao;

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

        @Test
        public void show(){
            Device device = new Device() ;
            Device deviceEntity = new Device() ;
            deviceEntity.setDeviceId(12L);
            Mockito.when(deviceDao.save(device)).thenReturn(deviceEntity);

            Mockito.when(deviceManagementServiceImpl.show()).thenReturn(null) ;
        }

    }

如果我使用类似这样的东西

Mockito.when(deviceDao.findByDeviceSerialNo("234er")).thenReturn(deviceEntity); 

然后它运行并为我提供了Device的非空对象。

这是什么原因?


然后它就能正常工作并给我一个非空的设备对象。请问问题是什么?非空对象? - Nirmal
1个回答

38
你设置模拟对象在接收到给定的设备对象时返回某些内容:
        Device device = new Device() ;
        Mockito.when(deviceDao.save(device)).thenReturn(deviceEntity);
这告诉你的deviceDao模拟在收到device作为save方法的参数时返回deviceEntity
Mockito使用equals进行参数匹配。这意味着,如果您调用deviceDao.save(x),则当x.equals(device)为真时,将返回deviceEntity
您的方法:
public String  show(){
        Device device = new Device() ;
        device.setContactName("abc");
        Device deviceEntity = deviceDao.save(device);
        System.out.println(deviceEntity);  // i get this null always Why ???
        return "demo";
}

这会在一个新的Device实例上调用save()方法。 我非常怀疑这个device与你设置模拟时使用的那个是相等的。

解决这个问题的一种方法是在测试中使用更广泛的匹配器:

Mockito.when(deviceDao.save(any(Device.class)).thenReturn(deviceEntity);

或者仅仅是为了确保您设置模拟时使用的Device与代码中使用的相同。我无法为您提供示例,因为您的问题没有包括Device.equals()的代码。


OffsetDateTime有一个有效且良好的equals()方法。我建议您找出为什么没有收到您正在寻找的OffsetDateTime实例,而不是使用any() - GuiSim
现在我看到了日期时间问题已经不存在且不相关了。但是在没有使用 any() 的情况下,Mockito仅在我告诉它返回已创建对象时返回 null 。只有使用 any(),我的jsonpath验证才会成功。奇怪。 - WesternGun
@GuiSim 再问一个问题...在一个测试用例中自动装配了一个Repository并使用了.save()方法进行保存...当调用userService.insertSome("ABC")时,发现该Repository的值为null...请帮忙解决。 - Salman S
@SalmanS 对不起,我不明白。您能否重现并链接到存储库? - GuiSim
听起来你正在调用一个有多个参数的方法上使用了 when。如果你在其中一个参数使用了 any(Device.class),那么你需要为所有参数提供匹配器。例如,如果你有 doSomething(device, string1, string2),那么你需要这样写:doSomething(any(Device.class), eq(string1), eq(string2)) - GuiSim
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接