带有 Spring Boot 的 Junit 5:何时使用 @ExtendWith Spring 或 Mockito?

新手上路,请多包涵

我有以下 抽象单元测试类,我的所有具体单元测试类都扩展了:

 @ExtendWith(SpringExtension.class)
//@ExtendWith(MockitoExtension.class)
@SpringBootTest(
    classes = PokerApplication.class,
    webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT
)
public abstract class AbstractUnitTests {

    @MockBean
    public RoundService roundService;

    @MockBean
    public RoundRepository roundRepository;
}

使用 @ExtendWith(SpringExtension.class)@ExtendWith(MockitoExtension.class) 有什么区别?

我问,因为使用任何一个注释似乎都没有区别,并且都在我的代码中分别工作——允许我使用 Junit5。那么为什么两者都起作用呢?

具体测试类:

     @DisplayName("Test RoundService")
    public class RoundsServiceTest extends AbstractUnitTests {

        private static String STUB_USER_ID = "user3";

        // class under test
        @InjectMocks
        RoundService roundService;

        private Round round;

        private ObjectId objectId;

        @BeforeEach //note this replaces the junit 4 @Before
        public void setUp() {

            initMocks(this);
            round = Mocks.round();
            objectId = Mocks.objectId();
        }

        @DisplayName("Test RoundService.getAllRoundsByUserId()")
        @Test
        public void shouldGetRoundsByUserId() {

            // setup
            given(roundRepository.findByUserId(anyString())).willReturn(Collections.singletonList(round));

            // call method under test
            List<Round> rounds = roundService.getRoundsByUserId(STUB_USER_ID);

            // asserts
            assertNotNull(rounds);
            assertEquals(1, rounds.size());
            assertEquals("user3", rounds.get(0).userId());
        }
}

相关的 Build.gradle 部分

 dependencies {
    implementation 'org.springframework.boot:spring-boot-starter'
    implementation 'org.springframework.boot:spring-boot-starter-data-mongodb'
    compile group: 'org.springframework.boot', name: 'spring-boot-starter-web', version: '2.2.2.RELEASE'

    compileOnly 'org.projectlombok:lombok'
    annotationProcessor 'org.projectlombok:lombok'

    testImplementation('org.springframework.boot:spring-boot-starter-test') {
        exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
    }
    implementation 'junit:junit:4.12'
}

test {
    useJUnitPlatform()
}

原文由 java12399900 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.9k
2 个回答

什么是 Junit 扩展

Junit 5 扩展的目的是扩展测试类或方法的行为

资源

阅读 Junit 5 扩展模型& @ExtendWith 注释: 这里

SpringExtension

SpringExtension 将 Spring TestContext Framework 集成到 JUnit 5 的 Jupiter 编程模型中。

 public class SpringExtension
extends Object
implements BeforeAllCallback, AfterAllCallback, TestInstancePostProcessor, BeforeEachCallback, AfterEachCallback, BeforeTestExecutionCallback, AfterTestExecutionCallback, ParameterResolver{..}

MockitoExtension

这个扩展是 JUnit Jupiter 等同于我们的 JUnit4 MockitoJUnitRunner

 public class MockitoExtension
extends java.lang.Object
implements BeforeEachCallback, AfterEachCallback, ParameterResolver{..}

可以看出, SpringExtensionMockitoExtension —实现了更多的扩展。

另外 @SpringBootTest 是用 @ExtendWith(SpringExtension.class) --- 进行元注释的,这意味着每次你的测试都用 SpringExtension 扩展。 @MockBean 是一个 Spring 测试框架注释,与 @ExtendWith(SpringExtension.class) 一起使用

要观察差异,请尝试以下操作

ExtendWith 只有 MockitoExtension

 @ExtendWith(MockitoExtension.class)
class TestServiceTest {

    @MockBean
    TestService service;

    @Test
    void test() {
        assertNotNull(service); // Test will fail
    }

}

ExtendWith 只有 SpringExtension

 @ExtendWith(SpringExtension.class)
class TestServiceTest {

    @MockBean
    TestService service;

    @Test
    void test() {
        assertNotNull(service); // Test succeeds
    }

}

ExtendWithSpringExtensionMockitoExtension

 @ExtendWith(MockitoExtension.class)
@ExtendWith(SpringExtension.class)
class TestServiceTest {

    @MockBean
    TestService service;

    @Test
    void test() {
        assertNotNull(service); // Test succeeds
    }

}

由于测试类的 @SpringBootTest 注释,如前所述,两者都适用于您的情况。

回答问题:何时使用 @ExtendWith Spring 或 Mockito? ,

当测试需要 Spring 测试上下文(自动装配 bean/使用 @MockBean )以及 JUnit 5 的 Jupiter 编程模型时,使用 @ExtendWith(SpringExtension.class) 。这也将通过 TestExecutionListeners 支持 Mockito 注释。

当测试使用 Mockito 并且需要 JUnit 5 的 Jupiter 编程模型支持时使用 @ExtendWith(MockitoExtension.class)

希望这可以帮助

原文由 R.G 发布,翻译遵循 CC BY-SA 4.0 许可协议

何时 使用@ExtendWith(SpringExtension.class) 或@SpringBootTest?

  • 当您使用集成测试-@SpringBootTest 注释-或任何切片测试-@xxxTest 注释-您不需要@ExtendWith(SpringExtension.class) 注释,因为提到的注释包含它。

  • 如果您测试@ConfigurationProperties、@Service、@Component 注解类(未在切片测试用例中定义 - 参考:Spring Boot 参考文档测试/自动配置/切片测试项-,您可以使用 @ExtendWith(SpringExtension.class) 而不是@SpringBootTest。

观察:我希望使用@ExtendWith(SpringExtension.class) 的测试比使用@SpringBootTest 进行的相同测试更快。当我在 Eclipse 中执行测试时,我观察到相反的情况。

原文由 a.lgl 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题