使用 @MockBean 的 Spring Boot 测试无法模拟映射器

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

我目前正在开发 Spring Boot 应用程序,我正在尝试使用 @MockBean 为我的服务层编写测试,以避免与数据库交互。这是测试代码:

//CountCarts Method in CartServiceImpl
//    @Override
//    public int countCarts(Cart cart) {
//        return cartMapper.countCarts(cart);
//    }

@SpringBootTest(classes = TestApplication.class)
@AutoConfigureMockMvc
class CartServiceImplTest {
    @MockBean
    private CartMapper cartMapper;
    @Autowired
    private CartServiceImpl cartService;
    @Test
    void testCountCarts() {
        Cart cart = new Cart();
        int count = 1;
        when(cartMapper.countCarts(Mockito.any())).thenReturn(count);
        assertEquals(count, cartService.countCarts(cart));
        //verify(cartMapper).countCarts(cart);
    }
}

但是,测试失败并出现以下错误:

Tests run: 1, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 3.777 s <<< FAILURE! - in CartServiceImplTest
testCountCarts  Time elapsed: 0.809 s  <<< FAILURE!
org.opentest4j.AssertionFailedError: expected: <1> but was: <5>
    at CartServiceImplTest.testCountCarts(CartServiceImplTest.java:46)

@MockBean 注释似乎没有按预期工作,测试仍在连接到我的数据库。

这是我的测试上下文的配置:

@ComponentScan(basePackages = {"world.xuewei"}, excludeFilters = {@ComponentScan.Filter(classes = {SpringBootApplication.class})
})
@SpringBootConfiguration
@EnableAutoConfiguration
@MapperScan(basePackages = {"world.xuewei.mapper"})
public class TestApplication {
    public static void main(String[] args) {
        SpringApplication.run(TestApplication.class, args);
    }

}

为了解决问题,我尝试删除 @MapperScan(basePackages = {"world.xuewei.mapper"}) 注释。但是,这导致了不同的错误:

java.lang.IllegalStateException: Failed to load ApplicationContext
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'addressController': Unsatisfied dependency expressed through field 'addressService'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'addressService': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'world.xuewei.mapper.AddressMapper' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@javax.annotation.Resource(shareable=true, lookup="", name="", description="", authenticationType=CONTAINER, type=java.lang.Object.class, mappedName="")}

我不知道如何继续。任何有关如何解决此问题的建议将不胜感激。预先感谢!

java spring-boot mockito junit5
1个回答
0
投票

由于您将配置

TestApplication
传递给
@SpringBootTest
注释,Spring 仅创建在
TestApplication
中配置的 bean,并且缺少一些必需的 bean,这就是您看到有关缺少 bean 的错误的原因。 您需要在
TestApplication
中定义所有丢失的bean,或者启用组件扫描以提供Spring扫描包。

但我看到测试本身的一个思想问题,如果您不打算测试与数据库的集成,则不需要使用

SpringBootTest
并创建上下文。使用 Mockito 进行单元测试要容易得多。

@RunWith(MockitoJUnitRunner.class) // or @ExtendWith depends on versions
class CartServiceImplTest {

private CartMapper cartMapper;

private CartServiceImpl cartService;

@Before
private void setup() {
  cartMapper = Mockito.mock();
  cartService = new CartService(cartMapper);
}

@Test
void testCountCarts() {
    Cart cart = new Cart();
    int count = 1;
    when(cartMapper.countCarts(Mockito.any())).thenReturn(count);
    assertEquals(count, cartService.countCarts(cart));
    //verify(cartMapper).countCarts(cart);
}

}

© www.soinside.com 2019 - 2024. All rights reserved.