我如何像 Mockito 一样实现它?

问题描述

我目前正在开展一个管理预订系统的项目。
一个新要求,即能够跟踪所有预订状态的变化。
我希望这不会影响现有的逻辑,并作为一个独立的模块存在。

一开始我想到了AOP,但是有一些问题。
这个请求应该记录什么数据是如何被什么操作改变的。

我认为我可以通过将 AOP 应用于存储库的保存方法提取不同的数据。
但是,这是不可能的,因为有许多不同的操作可以更新数据。

比如reservation,使用repository中的save方法进行更新,但是这个方法用于check in、check out等各种动作。
因此,可以得到数据的差异,但无法判断数据更新的是哪个动作。

@Service
public class BookingService {
    @Autowired
    private BookingRepository bookingRepository;

    public Booking create(Booking booking) {
        return bookingRepository.save(booking);
    }

    public void update(Booking booking) {
        Booking oldBooking = bookingRepository.findById(booking.getId()).orElseThrow(() -> new RuntimeException("Entity not found"));
        oldBooking.update(booking);

        bookingRepository.save(oldBooking);
    }

    public void checkIn(long id) {
        Booking booking = bookingRepository.findById(id).orElseThrow(() -> new RuntimeException("Entity not found"));

        booking.setStatus(Booking.Status.CheckIn);

        bookingRepository.save(booking);
    }
}

而且由于我使用 AOP,我不希望现有逻辑的参数或结果值适合某种形式。

在考虑如何解决这个问题的同时,使用Mockito使用的方法如何。
在 Mockito 中,我们可以知道一个方法何时在一个方法中执行。

例如,难道不能创建这样的方法吗?

@Aspect
public class BookingHistory {
    @Autowired
    private BookingRepository bookingRepository;

    @Around("execution(* *Service.update(..))")
    public void update(ProceedingJoinPoint proceedingJoinPoint) {
        long id = getBookingId(proceedingJoinPoint);
        Booking origin = getBooking(id);

        final DiffData diffData;
        when(bookingRepository::save).thenReturn(result -> diffData = diff(origin,result));
        saveHistory("UPDATE","Booking",diffData);
    }
}

但我不知道如何在 Mockito 中实现“when”、“thenReturn”等。

我能得到一些实现 Mockito 的提示吗?

如果不是这样,还有其他好的方法吗?

解决方法

Mockito 是一个测试框架,应该只用于单元测试。如果您想使用 Spring 的 AOP 跟踪哪个方法更改了数据,您可以使用自定义注解。使用自定义注释,您可以只传递标识操作的值并对其执行任何操作,例如:记录它、将其发布到 MQ 进行分析等。尝试以下 article 创建自定义注释和{ {3}} 如何获取方法的调用者信息。