我目前正在开发 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="")}
我不知道如何继续。任何有关如何解决此问题的建议将不胜感激。预先感谢!
由于您将配置
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);
}
}