- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
此问题涉及this one 。一旦确定了问题并成功应用了建议的解决方案,我就继续开发和重构我的代码,直到达到这一点。
正如您在下面的代码中看到的,我为在 Controller GetExchangeRate
中实例化的服务类定义了一个 bean,因此我将其直接注入(inject) Controller 并避免注入(inject)其依赖项(ExchangeRateView
是一个存储库,其实现使用 JdbcTemplate
)。然后,我重构了我的测试,因此我不需要模拟 ExchangeRateView
,而是模拟 GetExchangeRate
。但是,执行此操作后,我收到 Application failed to start
错误,提示
Parameter 0 of constructor in com.fx.exchangerate.store.infrastructure.persistence.read.ExchangeRateJdbcView required a bean of type 'org.springframework.jdbc.core.JdbcTemplate'
在我看来,即使我通过 @MockBean
注释模拟 GetExchangeRate
,它仍然试图从应用程序上下文中获取其依赖项,因为每当我将 @MockBean ExchangeRateView ExchangeRateView
添加到测试类时它都会正常运行。
所以我的问题是,@MockBean
真的有这样的行为吗?模拟类是否仍然需要注入(inject)其依赖项?我在这里遗漏了什么吗?
Controller :
@RestController
public class ExchangeRateStoreController {
private AddExchangeRateRequestAdapter addExchangeRateRequestAdapter;
private GetExchangeRate getExchangeRate;
private CommandBus commandBus;
@Autowired
public ExchangeRateStoreController(CommandBus commandBus, GetExchangeRate getExchangeRate) {
addExchangeRateRequestAdapter = new AddExchangeRateRequestAdapter();
this.commandBus = commandBus;
this.getExchangeRate = getExchangeRate;
}
@GetMapping
public ExchangeRate get(@RequestBody GetExchangeRateRequest getExchangeRateRequest) {
GetExchangeRateQuery query = new GetExchangeRateQuery(getExchangeRateRequest.from, getExchangeRateRequest.to, getExchangeRateRequest.date);
return getExchangeRate.execute(query);
}
@PostMapping
@ResponseStatus(HttpStatus.CREATED)
public void create(@RequestBody AddExchangeRateRequest addExchangeRateRequest) {
commandBus.dispatch(addExchangeRateRequestAdapter.toCommand(addExchangeRateRequest));
}
}
测试:
@RunWith(SpringRunner.class)
@WebMvcTest(ExchangeRateStoreController.class)
public class ExchangeRateStoreControllerTest {
@Autowired
private MockMvc mvc;
@MockBean
ExchangeRateRepository exchangeRateRepository;
@MockBean
ExchangeRateDateValidator exchangeRateDateValidator;
@MockBean
GetExchangeRate getExchangeRate;
@Test
public void givenValidAddExchangeRateRequest_whenExecuted_thenItReturnsAnHttpCreatedResponse() throws Exception {
String validRequestBody = "{\"from\":\"EUR\",\"to\":\"USD\",\"amount\":1.2345,\"date\":\"2018-11-19\"}";
doNothing().when(exchangeRateDateValidator).validate(any());
doNothing().when(exchangeRateRepository).save(any());
mvc.perform(post("/").content(validRequestBody).contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isCreated());
}
@Test
public void givenGetExchangeRateRequestThatMatchesResults_whenExecuted_thenItReturnsOkResponseWithFoundExchangeRate() throws Exception {
when(getExchangeRate.execute(any(GetExchangeRateQuery.class))).thenReturn(anExchangeRate());
mvc.perform(get("/")
.content("{\"from\":\"EUR\",\"to\":\"USD\",\"date\":\"2018-11-19\"}")
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk());
}
}
申请服务:
public class GetExchangeRate {
private ExchangeRateView view;
private Clock clock;
public GetExchangeRate(ExchangeRateView view, Clock clock) {
this.view = view;
this.clock = clock;
}
// More methods here
}
存储库实现类:
@Repository
public class ExchangeRateJdbcView implements ExchangeRateView {
JdbcTemplate jdbcTemplate;
@Autowired
public ExchangeRateJdbcView(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
// More methods here
}
配置类别:
@Configuration
public class ExchangeRateStoreConfig {
@Bean
@Autowired
public GetExchangeRate getExchangeRate(ExchangeRateView exchangeRateView, Clock clock) {
return new GetExchangeRate(exchangeRateView, clock);
}
@Bean
public Clock clock() {
return new Clock();
}
// More bean definitions
}
最佳答案
我终于找到了这个问题的根本原因。我发现这是由于我将 @ComponentScan(basePackages = {"com.mycompany.myapp.infrastruct", "com.mycompany.myapp.application"} )
添加到我的 Spring Boot 的主类中,因此 @WebMvcTest
无法正常运行。
你可以在spring boot的文档中找到解释:
If you use a test annotation to test a more specific slice of your application, you should avoid adding configuration settings that are specific to a particular area on the main method’s application class.
The underlying component scan configuration of @SpringBootApplication defines exclude filters that are used to make sure slicing works as expected. If you are using an explicit @ComponentScan directive on your @SpringBootApplication-annotated class, be aware that those filters will be disabled. If you are using slicing, you should define them again.
https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-testing.html
关于java - Spring boot @MockBean 疏远行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53545831/
我正在尝试使用@MockBean; java 版本 11、Spring Framework 版本 (5.3.8)、Spring Boot 版本 (2.5.1) 和 Junit Jupiter (5.7
我有一个使用多种服务的 Controller 类。我为该 Controller 编写了一个测试,例如: @RunWith(SpringRunner.class) @WebMvcTest(value =
在我的 Spring Boot 测试中,我使用了 2 个具有不同限定符的模拟 bean: @RunWith(SpringRunner.class) @SpringBootTest class Hoho
是否可以用真正的@Bean替换继承的@MockBean? 我有一个抽象类,它为所有 ITest 定义了许多配置和设置。仅对于一个测试,我想使用真实的 bean,而不是使用模拟的 bean。但仍然继承其
我有一个将被其他集成测试使用的基本测试场景。此方案包括一些用于外部集成的模拟 bean ( @MockBean )。 今天,我在集成测试类中有这样的东西: @SpringBootTest @WebAp
似乎返回 void 的模拟bean 在测试对象内部调用时不会抛出错误。我可以在外面调用它,但它会抛出错误。我的使用方式有问题吗? //some imports ... @RunWith(SpringR
我可以在 Controller 中使用@Autowired,例如 @RestController public class Index { @Autowired HttpServlet
我有一个使用 @WebMvcTest 的 Spring Boot 测试。我需要更新正在测试的 Controller ,以便它现在接受 Item 列表作为构造函数参数。该元素列表在构造函数中进行解析,以
我有一个配置类,其中有一些 MockBeans 替换了上下文中的实际 bean 以进行测试。 @Configuration public class MyTestConfig { @MockB
我有这个类定义 @RestController public class ReservationController { @Autowired private Reservation
在 Spring 应用程序中,可以使用默认 Autowiring 的模拟 bean 编写测试,并且可以使用常用的 Mockito 方法进一步自定义。为此,使用了@MockedBean 注释。但是,当只
我在 Spring Framework 上运行了几个集成测试,它们扩展了名为 BaseITCase 的基类。 像这样: @RunWith(SpringJUnit4ClassRunner.class)
我有一个 Spring Boot 1.4.2 应用程序。在启动期间使用的一些代码如下所示: @Component class SystemTypeDetector{ public enum S
目录 一个测试方法主要包括三部分 Junit 基本注解介绍 测试方法执行顺序 测试方法命名约定 基于 Spring 的单元测试编写
有了 JUnit,我可以很容易地使用 @MockBean : @SpringBootTest(classes = AppConfig.class) @RunWith(SpringRun
我正在使用 Cucumber 和 Spring Boot 进行测试 @CucumberContextConfiguration @ActiveProfiles(profiles = { "cucumb
我正在使用 Cucumber 和 Spring Boot 进行测试 @CucumberContextConfiguration @ActiveProfiles(profiles = { "cucumb
此问题涉及this one 。一旦确定了问题并成功应用了建议的解决方案,我就继续开发和重构我的代码,直到达到这一点。 正如您在下面的代码中看到的,我为在 Controller GetExchangeR
我有多个安全测试类,我在其中测试对不同 REST 端点的授权,我想模拟 ApplicationContext 将启动的所有存储库的 beans。我正在运行测试并且一切正常,但我不想在每个安全测试类中重
我正在尝试 @MockBean 一个 @Repository 注释类: @Repository public interface ApplicationDao extends MongoReposit
我是一名优秀的程序员,十分优秀!