4

我对弹簧集成测试有疑问。

行为:

  • 当我单独运行下面的测试时,它是成功的。

  • 但是,当所有测试都运行时,其中许多测试包括下面的测试都是错误的。

  • 当我忽略下面的测试并运行所有测试时,一切都成功了。

我没有包含错误堆栈跟踪,因为它与我们的业务逻辑高度相关,我怀疑该错误与我对 spring boot test 的使用有关@SpyBean

这是测试:

@RunWith(SpringRunner.class)
@ActiveProfiles(profiles = "test")
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)

...

@Autowired
private TestRestTemplate restTemplate;

@Autowired
private DataKeyStore dataKeyStore;

@SpyBean
private TokenTools tokenTools;

...

@Test
public void myTest() throws Exception {

   doReturn("someGeneratedToken")
        .doReturn("someGeneratedToken")
        .doCallRealMethod()
        .when(tokenTools)
        .createToken(any(TokenProfile.class), anyString(), anyString());
  ...

请注意,这DataKeyStoreTokenTools.

正如我上面所说,我怀疑测试正在互相踩踏,并且我@SpyBean在其他测试类上以某种方式泄漏......

我的问题是如何确保此测试不会踩到其他测试?我试过@DirtiesContext注释无济于事......

另外让我感到困惑的@SpyBean是已经重置(根据文档/javadoc)。

有人可以帮忙吗?

编辑:使用我的 IDE 调试测试表明TokenTools所有测试仅实例化两次:一次在测试初始化​​时,第二次用于@SpyBean为上面的测试创建。在上述测试之后运行的其余测试使用第二个实例,即@SpyBean实例......

4

2 回答 2

2

我最近遇到了同样的问题。确保为您的 @DirtiesContext注释设置正确的 classMode。

默认情况下,@DirtiesContext@SpyBean在完成测试类后重置。您可能希望在每个测试方法之前或之后重置它。

所以添加@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD)or@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)到你的测试类。

于 2019-07-31T14:24:45.533 回答
1

我可以确认这@DirtiesContext对我们也不起作用。@DirtiesContext在关闭旧上下文(通过注释)后,我们在为新上下文初始化 DB(使用 Liquibase)时遇到了问题。

我们最终为伪造一些本的测试以不同的方式命名 Spring 测试上下文:

例如:

@RunWith(SpringRunner.class)
@SpringBootTest
@ContextConfiguration(classes = SpringBootApp.class, name = "mainContext")
public class TestThatDoesntFakeBeans(){
}

@RunWith(SpringRunner.class)
@SpringBootTest
@ContextConfiguration(classes = SpringBootApp.class, name = "contextWithFakeBean")
public class TestThatFakeBeans(){
    @SpyBean
    //...
}

这样,为每个名称创建了单独的 Spring 上下文。具有相同名称的上下文被测试重用。但当然,您需要确保具有相同上下文名称的测试不会相互影响。

于 2017-03-23T14:51:19.663 回答