首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >带有Spring的Junit 5:何时使用@ExtendWith Spring或Mockito?

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

Stack Overflow用户
提问于 2020-04-25 23:10:19
回答 3查看 58.7K关注 0票数 52

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

代码语言:javascript
运行
复制
@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。那为什么两者都起作用呢?

混凝土测试类:

代码语言:javascript
运行
复制
    @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节

代码语言:javascript
运行
复制
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()
}
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2020-04-26 03:57:32

什么是Junit扩展

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

来源

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

SpringExtension

SpringExtension将Spring TestContext框架集成到JUnit 5的木星编程模型中。

代码语言:javascript
运行
复制
public class SpringExtension
extends Object
implements BeforeAllCallback, AfterAllCallback, TestInstancePostProcessor, BeforeEachCallback, AfterEachCallback, BeforeTestExecutionCallback, AfterTestExecutionCallback, ParameterResolver{..}

MockitoExtension

这个扩展是JUnit木星相当于我们的JUnit4 MockitoJUnitRunner

代码语言:javascript
运行
复制
public class MockitoExtension
extends java.lang.Object
implements BeforeEachCallback, AfterEachCallback, ParameterResolver{..}

可以看到,SpringExtension实现的扩展比MockitoExtension多得多。

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

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

ExtendWith仅限MockitoExtension

代码语言:javascript
运行
复制
@ExtendWith(MockitoExtension.class)
class TestServiceTest {

    @MockBean
    TestService service;

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

}

ExtendWith仅限SpringExtension

代码语言:javascript
运行
复制
@ExtendWith(SpringExtension.class)
class TestServiceTest {

    @MockBean
    TestService service;

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

}

ExtendWith兼有SpringExtensionMockitoExtension

代码语言:javascript
运行
复制
@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的木星编程模型时,使用@ExtendWith(SpringExtension.class)。这将通过TestExecutionListeners支持Mockito注释。

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

希望这能有所帮助

票数 62
EN

Stack Overflow用户

发布于 2021-09-28 07:00:08

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

  • 当您使用Integration -@SpringBootTest注释(或任何片测试-@xxxTest注释)时,您不需要@ExtendWith(SpringExtension.class)注释,因为前面提到的注释包括它。
  • 如果您测试@ConfigurationProperties,@Service,@Component注释类(未在片测试用例中定义-ref:SpringBootTest参考文档测试/自动配置/切片测试项),则可以使用@ExtendWith(SpringExtension.class)代替@SpringBootTest。

观察:我期望使用@ExtendWith(SpringExtension.class)的测试比使用@SpringBootTest.When的相同测试快,我在@SpringBootTest.When中执行了一个测试,我观察到了相反的情况。

票数 11
EN

Stack Overflow用户

发布于 2022-06-09 09:51:01

为了添加一些额外的信息:我最近还发现,如果您在带有@Mock的测试类中使用带有MockitoExtension注释的依赖项,并且尝试在@BeforeAll安装方法中使用Mockito.when(mockedDependency.methodName()),那么您将在模拟的依赖项上得到一个NullPointer

但是,如果将MockitoExtension更改为SpringExtension,则工作正常。看起来,使用SpringExtension时,模拟bean会在前面( JUnit启动@BeforeAll方法之前)初始化,就像它应该正常工作一样。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61433806

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档