如何使用 Mockito 框架模拟我的服务
Posted
技术标签:
【中文标题】如何使用 Mockito 框架模拟我的服务【英文标题】:How to mock my service using Mockito framework 【发布时间】:2021-12-27 14:43:43 【问题描述】:您好,我正在努力按照下面的方法编写一个模拟测试;
下面是我的代码;
@Component
public class CodeConfigBuilder
@Value("$promoConfig.prefix.length")
private Integer prefixLength;
public void validateRequestAndSetDefaults(PromoRequest promoRequest)
prefixAndPostFixControlAccordingToLength(promoRequest);
private void prefixAndPostFixControlAccordingToLength(PromoRequest promoRequest)
if (promoRequest.getPostfix() != null)
int lengthControl = prefixLength + promoRequest.getPostfix().length();
if (lengthControl >= promoRequest.getLength())
throw new BadRequestException(Constant.ClientConstants.THE_SUM_OF_PREFIX_AND_POSTFIX_CAN_NOT_BE_GREATER_THAN_LENGHT);
下面是我的yml配置;
#========= Promo Config ========== #
promoConfig:
prefix:
length: 3
下面是我的服务;
public void validateRequest(PromoRequest promoRequest)
codeConfigBuilder.validateRequestAndSetDefaults(promoRequest);
我创建了一个 PropertySourceResolver 类
@Component
@Getter
public class PropertySourceResolver
private int prefixLength = 3;
下面还有我的测试课;
@RunWith(MockitoJUnitRunner.class)
class CodeConfigBuilderTest
@MockBean
private PropertySourceResolver propertySourceResolver = new PropertySourceResolver();
@InjectMocks
private PromoRequest promoRequest = new PromoRequest();
@InjectMocks
private PromoService Service;
@Before
public void init()
promoRequest.setPrefix("ABC");
promoRequest.setPostfix("ABCDABCD");
promoRequest.setQuantity(10);
promoRequest.setLength(12);
promoRequest.setCharset("ABCDEF");
@Test
public void prefixAndPostFixControl_accordingToLength_for_Succeed()
int lengthControl = promoRequest.getPrefix().length() + promoRequest.getPostfix().length();
if (lengthControl >= promoRequest.getLength())
Assert.assertTrue(false);
我喜欢根据测试场景更改我的代码,例如;当......然后返回任何想法?谢谢。
【问题讨论】:
到底是什么问题?有什么事情没有按照您的预期工作? 我喜欢更改我的代码: (当...).thenReturn()CodeConfigBuilder
是一个简单的服务,为什么你认为你需要 mockito 来测试它?创建一个有效的PromoRequest
并将其传递给validateRequestAndSetDefaults
,它不应该抛出。然后创建一个无效的PromoRequest
,validateRequestAndSetDefaults
会抛出。使用构造函数注入来简化CodeConfigBuilder
的创建
所以您希望prefixLength 可以在您的测试中即时调整,对吗?
@lesika 你介意写一下怎么做吗谢谢
【参考方案1】:
为了使这更简单和更好地组织您的代码,通过创建以下类来抽象注入配置的复杂性:
@ConfigurationProperties(prefix = "promoConfig.prefix")
public class PromoPrefixConfiguration
private Integer length;
public Integer getLength()
return length;
然后,您应该将此作为 CodeConfigBuilder
的依赖项:
@Component
public class CodeConfigBuilder
private Integer prefixLength;
public CodeConfigBuilder(PromoPrefixConfiguration promoPrefixConfiguration)
this.prefixLength = promoPrefixConfiguration.getLength();
public void validateRequestAndSetDefaults(PromoRequest promoRequest)
prefixAndPostFixControlAccordingToLength(promoRequest);
private void prefixAndPostFixControlAccordingToLength(PromoRequest promoRequest)
if (promoRequest.getPostfix() != null)
int lengthControl = prefixLength + promoRequest.getPostfix().length();
if (lengthControl >= promoRequest.getLength())
throw new BadRequestException(Constant.ClientConstants.THE_SUM_OF_PREFIX_AND_POSTFIX_CAN_NOT_BE_GREATER_THAN_LENGHT);
现在,为了测试这个类,您必须进行三个测试:
-
测试
PromoRequest
是否有效,因为postfix
为空;
测试PromoRequest
是否有效,因为长度有效;
测试PromoRequest
无效,因为长度无效;
它们将类似于以下内容:
class CodeConfigBuilderTest
private PromoPrefixConfiguration promoPrefixConfiguration = new PromoPrefixConfiguration(10);
private CodeConfigBuilder codeConfigBuilder = new CodeConfigBuilder(promoPrefixConfiguration);
@Test
public void promoRequestIsValidGivenNullPostfix()
// Arrange
PromoRequest promoRequest = new PromoRequest();
promoRequest.setPostfix(null);
// Act
codeConfigBuilder.validateRequestAndSetDefaults(promoRequest);
@Test
public void promoRequestIsValidGivenValidPrefixPlusPostfixLength()
// Arrange
PromoRequest promoRequest = new PromoRequest();
promoRequest.setPostfix("ABCD");
promoRequest.setLength(15);
// Act
codeConfigBuilder.validateRequestAndSetDefaults(promoRequest);
@Test(expected = BadRequestException.class)
public void promoRequestIsInvalidGivenInvalidPrefixPlusPostfixLength()
// Arrange
PromoRequest promoRequest = new PromoRequest();
promoRequest.setPostfix("ABCDEFGH");
promoRequest.setLength(15);
// Act
codeConfigBuilder.validateRequestAndSetDefaults(promoRequest);
如果您使用的是 JUnit 5,则可以将最后一个测试替换为以下测试,以轻松断言异常消息:
@Test
public void promoRequestIsInvalidGivenInvalidPrefixPlusPostfixLength()
// Arrange
PromoRequest promoRequest = new PromoRequest();
promoRequest.setPrefix("ABCDEFG");
promoRequest.setPostfix("HIJKLMN");
// Act
Exception exception = assertThrows(BadRequestException.class, () ->
codeConfigBuilder.validateRequestAndSetDefaults(promoRequest);
);
// Assert
String exceptionMessage = exception.getMessage();
assertTrue(exceptionMessage.equals(Constant.ClientConstants.THE_SUM_OF_PREFIX_AND_POSTFIX_CAN_NOT_BE_GREATER_THAN_LENGHT));
P.S.:你的意思是 suffix
而不是 postfix
?
【讨论】:
比你 Joao Dias 这很棒我的意思是后缀和后缀 togethar 不能大于长度 我的回答对您有帮助还是您还有疑问? Jao Dias 我真的很感激我正在尝试你的解决方案,但是我在 codeConfigBuilder 上得到了第二个参数,它是 public CodeConfigBuilder(PromoRepository promoRepository, PromoCodeConfiguration promoCodeConfiguration) this.promoRepository = promoRepository; this.prefixLength = promoCodeConfiguration.getLength(); promoRepository 如何从类中抽象出这个 repo 也许你不应该,在这种情况下,你需要在你的测试中模拟它并相应地调整它们。如果您创建一个新问题并在此处添加所有详细信息并在此处共享链接,那么会更容易为您提供帮助;)以上是关于如何使用 Mockito 框架模拟我的服务的主要内容,如果未能解决你的问题,请参考以下文章