Spock mock 未在 Spring Integration Test 中触发

问题描述 投票:0回答:0

我正在为这种情况绞尽脑汁(为了简短描述,下面的代码很简单,问题在于 jpa 存储库和一些 spring 上下文?):

@RequiredArgsConstructor
public class SomeClass {

  private final SomeJpaRepository repository;
  private final SomeBean someBean;

  private void method() {
    final String context = repository.findByName(contexName);
    someBean.doSthFurther(context);
  }
}

@RequiredArgsConstructor
public class SomeBean {

  private void doSthFurther() {
    //do sth
  }
}

@RequiredArgsConstructor
public class SomeService {
  private SomeClass someClass;
  public void execute() {
    //do stuff
    someClass.method();
    //do other stuff
  }
}

@TestConfiguration
class IntegrationTestMockingConfig {
    private DetachedMockFactory factory = new DetachedMockFactory()

    @Bean
    SomeBean someBean() {
        factory.Mock(SomeBean)
    }
}

@Testcontainers
@ActiveProfiles("integration-testing")
@SpringBootTest
@AutoConfigureMockMvc
class PostgresEnvironment extends Specification {

    @Autowired
    MockMvc mvc;

    static PostgreSQLContainer sQLContainer = new PostgreSQLContainer("postgres:latest")
            .withDatabaseName("foo")
            .withUsername("foo")
            .withPassword("secret")
            .withReuse(true)

    def setupSpec() {
        sQLContainer.start()
    }

    @DynamicPropertySource
    static void overrideProperties(DynamicPropertyRegistry registry){
        registry.add("spring.datasource.url", sQLContainer::getJdbcUrl);
        registry.add("spring.datasource.username", sQLContainer::getUsername);
        registry.add("spring.datasource.password", sQLContainer::getPassword);
        registry.add("spring.datasource.driver-class-name", sQLContainer::getDriverClassName);
    }
}

最后是我的规范场景:

@ContextConfiguration(classes = [IntegrationTestMockingConfig])
class ScenarioToBeVerified extends PostgresEnvironment {

    @Autowired SomeBean someBean;


    def "scenario to verify interactions"() throws Exception {

        given: ''

        def xyz = create()
        
        when:
        var response = someService.execute()

        then:
        1 * someBean.doSthFurther(_)
    }

}

这是一个简单的SpringBoot应用。问题是 1 * someBean.doSthFurther() 验证失败,因为交互为 0。 问题在于: final String context = repository.findByName(contexName); SomeService 调用 SomeClass 和它的方法 method() 进一步在内部调用 jpa 存储库和我的模拟类。

如果我删除这一行,则交互验证成功通过。我有一个绿色测试。如果我调用存储库交互验证失败。测试是红色的。

调用 jpa 存储库的行发生了什么?我不是在嘲笑它,我只是在嘲笑其他一些类,但似乎我的 SomeClass 有两个依赖项:

  1. jpa 存储库
  2. 一些被Spock嘲笑的类

失败(在调试模式下我可以看到 someBean.doSthFurther(context); 正在被调用。那么为什么规范看不到它并成功验证? 我的 Jpa 存储库很简单:

@Repository
public interface SomeJpaRepository extends JpaRepository<SomeEntity, UUID> {
  
}

@Entity
public class SomeEntity {
  @Id
  @GeneratedValue
  UUID id;
}

我完全迷路了 :( :( 我不使用 @SpringBean,因为我在其他规范之间共享我的模拟和存根。 Spock 版本 - 2.4-M1,弹簧启动 2.7.3

我会很感激一些建议...

spring mocking spock testcontainers
© www.soinside.com 2019 - 2024. All rights reserved.