[英]Using an interface for mocking purposes in unit tests for Java with Spring
I have a problem trying to mock interfaces in my API based on Spring.我在尝试模拟基于 Spring 的 API 中的接口时遇到问题。 I am getting this error:
我收到此错误:
Description:
Parameter 0 of constructor in bm.app.services.Service required a bean of type 'bm.app.services.DiscountProvider' that could not be found.
Action:
Consider defining a bean of type 'bm.app.services.DiscountProvider' in your configuration.
And I just don't understand it.我就是不明白。 I am adding an interface (DiscountProvider) as a parameter for a constructor of my service class (Service) in order to use Mockito for testing purposes.
我正在添加一个接口 (DiscountProvider) 作为我的服务 class (Service) 的构造函数的参数,以便将 Mockito 用于测试目的。
The beginning of my Service (I think the only relevant part here) looks like this:我的服务的开始(我认为这里唯一相关的部分)如下所示:
@org.springframework.stereotype.Service
public class Service {
DiscountProvider discountProvider;
public Service(DiscountProvider discountProvider) {
this.discountProvider = discountProvider;
}
The interface looks like this:界面如下所示:
import org.springframework.stereotype.Component;
import java.math.BigDecimal;
@Component
public interface DiscountProvider {
BigDecimal getThePriceOfTheProduct();
}
And my test class looks like that:我的测试 class 看起来像这样:
@Component
public class ServiceTests {
Service service;
DiscountProvider discountProvider;
@Test
@DisplayName("Should return the value higher by ten percent.")
void shouldReturnValueHigherByTenPercent() {
//given
Mockito.when(discountProvider.getThePriceOfTheProduct()).thenReturn(new BigDecimal("20.00"));
AdditionalMiniProduct product = new AdditionalMiniProduct(UUID.randomUUID(), new BigDecimal("300.00"), "Yellow Loan");
//when
BigDecimal result = service.increaseByGivenAmount(product.getNetPrice(), discountProvider.getThePriceOfTheProduct());
//then
assertThat(result).isEqualTo("315.00");
}
@Test
void shouldReturnACorrectRiskLevelValue() {
int months = 18;
assertEquals(5, calculateRiskLevelByNumberOfMonths(months));
}
@Test
void shouldReturnACorrectEnumValueBasedOnNumberOfMonths() {
int months = 26;
assertEquals(RiskLevel.HIGH, giveTheRiskNameBasedOnNumberOfMonths(months));
}
@Test
void shouldReturnAPriceOfAProvidedFinancialProduct() {
BigDecimal productPrice = new BigDecimal(1200);
String productName = "SilverLoan";
assertEquals(productPrice,findAProductPriceByGivenName(productName));
}
@BeforeEach
void setUp() {
service = new Service(discountProvider);
discountProvider = Mockito.mock(DiscountProvider.class);
}
}
Now, I am fairly new to testing, so I do expect to have made some rookie mistakes.现在,我对测试还很陌生,所以我确实预计会犯一些新手错误。 The thing is, that's my first attempt to have more "complex" unit tests run with one of my Spring apps and I just don't get it.
问题是,这是我第一次尝试使用我的 Spring 应用程序运行更“复杂”的单元测试,但我就是不明白。 It refuses to acknowledge the @Component (or any other I managed to find) annotation.
它拒绝承认@Component(或我设法找到的任何其他)注释。
If you are unit testing your Service
class, you should mock all external dependencies of this class under test.如果您正在对
Service
class 进行单元测试,则应模拟此 class 的所有外部依赖项。
Assuming you are using JUnit 5, a possible test setup can look like the following假设您使用的是 JUnit 5,可能的测试设置如下所示
@ExtendWith(MockitoExtension.class)
public class ServiceTest {
@Mock
private DiscountProvider discountProvider;
@InjectMocks
private Service service;
@Test
@DisplayName("Should return the value higher by ten percent.")
void shouldReturnValueHigherByTenPercent() {
//given
Mockito.when(discountProvider.getThePriceOfTheProduct()).thenReturn(new BigDecimal("20.00"));
AdditionalMiniProduct product = new AdditionalMiniProduct(UUID.randomUUID(), new BigDecimal("300.00"), "Yellow Loan");
//when
BigDecimal result = service.increaseByGivenAmount(product.getNetPrice(), discountProvider.getThePriceOfTheProduct());
//then
assertThat(result).isEqualTo("315.00");
}
}
In addition, you don't need @Component
for your test classes.此外,您的测试类不需要
@Component
。 This annotation is used for your production code to mark Spring beans.此注释用于您的生产代码以标记 Spring bean。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.