java - 单元测试时静态元模型属性为空

标签 java jpa testng

我在外部包中有@Entity 类,它也有静态元模型。在我的应用程序的服务类中,我使用这些元模型和 EntityManager/CriteriaBuilder/CriteriaQuery 来检索我的数据。这在运行应用程序时工作正常。但是,在运行单元测试时,我的元模型及其属性始终为空。

代码...

package com.example.core.entities;

@Entity
@Table(schema = "lookup", name="BookingSystem")
public class BookingSystem implements ILookupEntity, IAuditEntity, Serializable {
  @Id
  @GeneratedValue(strategy = IDENTITY)
  @Column(name = "id")
  public Integer id;

  @Column(name = "name")
  public String name;

  @Column(name = "code")
  public Integer code;
}

package com.example.core.entities;

@Generated(value = "org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor")
@StaticMetamodel(BookingSystem.class)
public abstract class BookingSystem_ {
  public static volatile SingularAttribute<BookingSystem, Integer> id;
  public static volatile SingularAttribute<BookingSystem, Integer> code;
  public static volatile SingularAttribute<BookingSystem, String> name;
}

在我的应用的服务类中的使用...

package com.example.bookingsystem;

@Service
public class BookingService {
  @PersistenceContext
  private EntityManager entityManager;

public void saveBooking(Booking booking) {
//...
  RepositoryQueryBuilder<BookingSystem> bookingSystemSelector = new RepositoryQueryBuilder<>(entityManager, BookingSystem.class);
  List<BookingSystem> bookingSystems = bookingSystemSelector
      .and(BookingSystem_.code, booking.bookingSystem.code) //<-- Here "BookingSystem_.code" is null.
      .getResultList();
  //...
  }
}

“RepositoryQueryBuilder”类只是一个实用程序构建器类,它包装了 EntityManager、CriteriaBuilder 等。基本上仿照此示例... JPA Criteria Predicate Conditions

单元测试代码...

package com.example.bookingsystem;

public abstract class BaseTestSetup {
  @InjectMocks
  protected BookingService bookingService;

  protected EntityManager entityManager = PowerMockito.mock(EntityManager.class);
  protected CriteriaBuilder criteriaBuilder = PowerMockito.mock(CriteriaBuilder.class);
  protected CriteriaQuery<BookingSystem> criteriaQuery = PowerMockito.mock(CriteriaQuery.class);
  protected Root<BookingSystem> root = PowerMockito.mock(Root.class);

  protected void arrange() {
    when(entityManager.getCriteriaBuilder()).thenReturn(criteriaBuilder);
    when(criteriaBuilder.createQuery(BookingSystem.class)).thenReturn(criteriaQuery);
    when(criteriaQuery.from(Matchers.<Class<BookingSystem>>any())).thenReturn(root);
    when(criteriaQuery.from(Matchers.<EntityType<BookingSystem>>any())).thenReturn(root);
}

@RunWith(PowerMockRunner.class)
public class BookingServiceTest extends BaseTestSetup {
  @BeforeClass
  @Override
  public void arrange() {
    super.arrange();

    //...
}

@Test
public void doIt() {
    Booking booking = new Booking();
    booking.id = 12345;
    booking.bookingSystem = new BookingSystem();
    booking.bookingSystem.id = 1;
    booking.bookingSystem.code = 106000;

    bookingService.saveBooking(booking);
  }
}

我看过这个JPA/Hibernate Static Metamodel Attributes not Populated -- NullPointerException ,但解决方案似乎是“确保实体及其元模型在同一个包中”,但如您所见,两者都已经在我的“com.example.core.entities”包中。

我在我的代码中使用了所有 bean 和注释驱动的配置(没有持久性或上下文 xml 文件)。就测试而言,我在 IntelliJ 中使用 TestNG 和 PowerMock。

在单元测试期间似乎没有提取元模型。任何想法。

最佳答案

加载 hibernate 时会填充静态元模型类。因此,要么在测试中配置 hibernate 上下文,要么在方法执行之前手动填充属性。在您的代码中,您可以:

@Test
public void doIt() {
    BookingSystem_.code = new SingularAttributeMock<BookingSystem, Integer>();
    bookingService.saveBooking(booking);
  }
}

SingularAttributeMock 可以定制创建以便在您的测试中使用它。您还可以使用 SingularAttribute 类的任何其他实现。

public class SingularAttributeMock<X, Y> implements SingularAttribute<X, Y> {
   //Overriding methods of SingularAttribute...
}

关于java - 单元测试时静态元模型属性为空,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36225377/

相关文章:

java - 在 Eclipse 中增强 openJPA 类

java - 无法从 TestNG Class ->java.lang.NullPointerException 调用两个单独类的属性

java - 如何将垂直 JDialog 大小调整限制为对话框中的单个组件?

java - 为什么使用 JPA/Eclipselink/Texo 进行批量插入比使用纯 JDBC 插入慢得多(!)?

java - 如何将 @ManyToMany 与同一个表上的两个列表一起使用

java - Spring MVCOptionalValidatorFactoryBean 未找到

java - TestNG - WebDriver - Web 应用程序测试 - 独立测试

selenium - Selenium Grid2:并行测试同时在同一浏览器上运行

java - 计算树上的匹配节点

java - java中的正则表达式代码