我正在为这种情况绞尽脑汁(为了简短描述,下面的代码很简单,问题在于 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 有两个依赖项:
失败(在调试模式下我可以看到 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
我会很感激一些建议...