gpt4 book ai didi

java - 定义 Spring 组件时出错

转载 作者:行者123 更新时间:2023-12-01 18:34:33 25 4
gpt4 key购买 nike

我想使用 Spring 定义一个我自己的组件。

下面是我的代码:

MyPasswordEncoderConfig:

@Configuration
@ComponentScan(basePackages = { "my.package" })
public class CryptoConfig {

@Bean
public PasswordEncoder getPasswordEncoder() {
return new BCryptPasswordEncoder();
}

}

MyPasswordEncoder:

@Component
public class MyPasswordEncoder {

@Autowired
private PasswordEncoder passwordEncoder; // Defined in Spring Security.

public String encode(String plainTextPassword) {
return passwordEncoder.encode(plainTextPassword);
}

public boolean matches(String encodedPasswordA, String encodedPasswordB) {
return passwordEncoder.matches(encodedPasswordA, encodedPasswordB);
}

}

MyPasswordEncoderTest:

@ContextConfiguration(classes = {MyPasswordEncoder.class, MyPasswordEncoderConfig.class})
@RunWith(SpringJUnit4ClassRunner.class)
public class MyPasswordEncoderTest {

@Mock
private PasswordEncoder passwordEncoder;

@InjectMocks
@Autowired
private MyPasswordEncoder myPasswordEncoder;

@Before
public void init() {
MockitoAnnotations.initMocks(this);
}

@Test
public void testPasswordMatching() {
String plainTextPassword = "ABCdef123@@@";
String encodedPassword = myPasswordEncoder.encode(plainTextPassword);
assertTrue(myPasswordEncoder.matches(plainTextPassword, encodedPassword));
}
}

当我运行测试时,它失败了。使用标准输出检查结果,passwordEncoder.encode(plainTextPassword); 返回 null 值。

我做错了什么?

更新:

问题与PasswordEncoder接口(interface)有关。如果我用BCryptPasswordEncoder替换它,测试就可以正常工作。

最佳答案

根据我从您的测试代码中收集到的信息,您实际上想要测试 MyPasswordEncoder 的功能。那么为什么要使用模拟呢?为什么不只对 PasswordEncoderMyPasswordEncoder 使用 @Autowired,如以下代码所示:

@ContextConfiguration(classes = {MyPasswordEncoder.class, MyPasswordEncoderConfig.class})
@RunWith(SpringJUnit4ClassRunner.class)
public class MyPasswordEncoderTest {

@Autowired
private PasswordEncoder passwordEncoder;

@Autowired
private MyPasswordEncoder myPasswordEncoder;

@Test
public void testPasswordMatching() {
String plainTextPassword = "ABCdef123@@@";
String encodedPassword = myPasswordEncoder.encode(plainTextPassword);
assertTrue(myPasswordEncoder.matches(plainTextPassword, encodedPassword));
}
}

如果您不想编写 Spring 集成测试,而是编写简单的单元测试,并且不想重构代码,您可以编写以下内容:

public class MyPasswordEncoderTest {

private PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();

private MyPasswordEncoder myPasswordEncoder = new MyPasswordEncoder();

@Before
public void init() {
ReflectionTestUtils.setField(myPasswordEncoder, "passwordEncoder", passwordEncoder);
}

@Test
public void testPasswordMatching() {
String plainTextPassword = "ABCdef123@@@";
String encodedPassword = myPasswordEncoder.encode(plainTextPassword);
assertTrue(myPasswordEncoder.matches(plainTextPassword, encodedPassword));
}
}

一个更好的解决方案(放弃使用 Spring ReflectionTestUtils)是像这样重构 MyPasswordEncoder:

@Component
public class MyPasswordEncoder {

private final PasswordEncoder passwordEncoder; // Defined in Spring Security.

@Autowired
public MyPasswordEncoder(PasswordEncoder passwordEncoder) {
this.passwordEncoder = passwordEncoder;
}

public String encode(String plainTextPassword) {
return passwordEncoder.encode(plainTextPassword);
}

public boolean matches(String encodedPasswordA, String encodedPasswordB) {
return passwordEncoder.matches(encodedPasswordA, encodedPasswordB);
}

}

然后单元测试将变成:

public class MyPasswordEncoderTest {

private MyPasswordEncoder myPasswordEncoder = new MyPasswordEncoder(new BCryptPasswordEncoder());

@Test
public void testPasswordMatching() {
String plainTextPassword = "ABCdef123@@@";
String encodedPassword = myPasswordEncoder.encode(plainTextPassword);
assertTrue(myPasswordEncoder.matches(plainTextPassword, encodedPassword));
}
}

关于java - 定义 Spring 组件时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22639258/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com