해결된 질문
작성
·
213
0
B라는 클래스에
@Autowired 로 C를 받고
C.start()라는 함수가 있을 때
BTest 클래스에서 C.start() 실행하면 C가 null포인트가 발생하는데 월래 Autowired로 받은 클래스는 Test에서 사용을 못하나요? Bean을 찾지를 못하는 것 같습니다.
답변 6
3
DTO 객체를 빈으로 등록해서 사용하는 것은 좋지 않습니다.
도메인 주도 설계 방식이라도 서비스단에서 주입을 해서 처리하는게 더 좋습니다.
DTO들은 가급적 순수하게 데이터만 들고 있는 것이 좋습니다.
꼭 필요하면 서비스에서 주입받은 PasswordEncoder 자체를 @Autowired가 아니라 PostAccount 사용 시점에 파라미터로 넘기는 것도 하나의 방법입니다.
이런식으로요.
public Account toAccount(PasswordEncoder encoder) {
...
}
감사합니다.
2
안녕하세요. Kim님
스프링 빈으로 등록해야 @Autowired가 적용됩니다.
PostAccount는 스프링 빈이 아니기 때문에 @Autowired가 적용되지 않습니다.
감사합니다.
0
0
답변감사합니다
DTO객체를 빈으로 등록해서 사용하기도 하나요?
저렇게 postaccount에서 암호화하는게 도메인주도 설계방식이라 생각되어서 저렇게 만들어 본것이거든요. 책임을 DTO로 준건데 그냥 서비스단에서 주입을 해서 로직을 처리하는게 나을까요?
0
회원기능을 만들어 볼려고하는 중이였습니다~
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Bean
public PasswordEncoder passwordEncoder(){
return PasswordEncoderFactories.createDelegatingPasswordEncoder();
}
@Override
public void configure(WebSecurity web) {
web.ignoring().requestMatchers(PathRequest.toStaticResources().atCommonLocations());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest().permitAll();
}
}
이렇게 PasswordEncoder를 Bean으로 등록하였습니다.
@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Account extends BaseTimeEntity implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String username;
private String password;
private String email;
@Builder
public Account(String username, String password, String email) {
this.username = username;
this.password = password;
this.email = email;
}
}
회원 정보 테이블입니다.
public interface AccountRepository extends JpaRepository<Account, Long>{
}
Repository입니다.
@Getter
@Setter
public class PostAccount {
@Autowired
PasswordEncoder passwordEncoder;
@NotBlank(message = "이름은 필수 값입니다.")
private String username;
@NotBlank(message = "비밀번호는 필수 값입니다.")
private String password;
@NotBlank(message = "이메일은 필수 값입니다")
@Pattern(regexp = "^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\\\.[A-Za-z]{2,6}$", message = "이메일 형식이 아닙니다.")
private String email;
@Builder
public PostAccount(@NotBlank(message = "이름은 필수 값입니다.") String username,
@NotBlank(message = "비밀번호는 필수 값입니다.") String password,
@NotBlank(message = "이메일은 필수 값입니다") @Pattern(regexp = "^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\\\.[A-Za-z]{2,6}$", message = "이메일 형식이 아닙니다.") String email
) {
this.username = username;
this.password = password;
this.email = email;
}
public Account toAccount(){
return Account.builder()
.password(passwordEncoder.encode(password))
.username(username)
.email(email)
.build();
}
}
PostAccount는 Account의 DTO입니다. toAccount 함수에서 .password(passwordEncoder.encode(password)) 이 부분이 문제가 됩니다.
@RunWith(SpringRunner.class)
@SpringBootTest
public class AccountTest {
@Autowired
AccountRepository accountRepository;
@Test
public void PostAccount_객체로_받아와서_Account_Entity_로_변환하고_DB에_저장하기(){
PostAccount postAccount = PostAccount.builder()
.username("ym")
.password("1234")
.email("ym@email.com")
.build();
Account save = accountRepository.save(postAccount.toAccount());
assertEquals("username은 ym이다", "ym",save.getUsername());
assertEquals("password는 1234이다", "1234", save.getPassword());
assertEquals("email은 ym@email.com이다","ym@email.com", save.getEmail());
}
}
이것이 실행한 테스트이고
java.lang.NullPointerException
at com.ym.shop.domain.account.dto.PostAccount.toAccount(PostAccount.java:43)
at com.ym.shop.domain.account.entity.AccountTest.PostAccount_객체로_받아와서_Account_Entity_로_변환하고_DB에_저장하기(AccountTest.java:29)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.springframework.test.context.junit4.statements.RunBeforeTestExecutionCallbacks.evaluate(RunBeforeTestExecutionCallbacks.java:74)
at org.springframework.test.context.junit4.statements.RunAfterTestExecutionCallbacks.evaluate(RunAfterTestExecutionCallbacks.java:84)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:251)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
null point에러가 발생합니다.
PostAccount에서
@Autowired
PasswordEncoder passwordEncoder;
이 부분이 테스트에서는 주입이 안되는 것 같습니다.
0
안녕하세요. kim님
뭔가 설정이 잘못된 것 같습니다^^
클래스 C가 스프링 빈으로 등록이 안된 것 같아요.
github 같은곳에 동작하는 코드를 올려주시면, 도움을 드릴께요^^