【问题标题】:How do I implement it like Mockito?我如何像 Mockito 一样实现它?
【发布时间】:2021-07-09 04:09:18
【问题描述】:

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

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

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

例如,对于预订,使用存储库中的保存方法进行更新,但此方法用于签入、签出等各种操作。
因此,可以得到数据的差异,但无法判断数据是由哪个动作更新的。

@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 的提示?

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

【问题讨论】:

  • 您使用什么持久性? JPA?普通的 JDBC?或者...
  • Spring 数据 JPA。
  • 假设你正在使用 Hibernate,只需使用 Hibernate Envers。哪个是开箱即用的,或者如果你想要别的东西,你也可以使用 JaVers。你不需要自己动手。如果所有其他方法都失败了,您甚至可以使用数据库上的触发器来执行此操作,以将原始数据复制到审计表中。如果你愿意,不需要在 java 中做。
  • 这根本不是 AOP 的工作方式。如果您想影响save 的返回值,只需编写一个带有截取其执行的切入点的建议,在那里执行您的差异操作并保存到审核日志中。如果您要发布完整的MCVE,我可以在本地运行它并提出具体建议。您目前正在隐藏信息,例如getBookingId(proceedingJoinPoint) 做了什么,Booking 类看起来像什么等等。但据我所知,如果你不喜欢 Javers,你可以使用 AOP 轻松解决问题。

标签: java spring architecture aop aspect


【解决方案1】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-09-10
    • 1970-01-01
    • 2021-12-09
    • 2021-11-02
    • 1970-01-01
    • 1970-01-01
    • 2013-03-23
    • 2012-02-07
    相关资源
    最近更新 更多