2017-01-15 10 views
0

私は最初のSpring MVC、Boot、Data web-appを作成しています。テストを作成する際に問題があります。私はCraig Wallの本「Spring in Action」のいくつかの例を修正しています。 私のコントローラ用のTDDテストを書こうとしましたが、方法registerNewAccountのために、すべてがOKだったと確信していましたが、いつも私はargumetns are different!を取得します。以下のフルスタックトレース:Spring MVCコントローラのTDDテストが正しく動作しない

Argument(s) are different! Wanted: 
accountService.create(
    [email protected] 
); 
-> at com.conf.controller.AccountControllerSpec.registerNewUser(AccountControllerSpec.java:52) 
Actual invocation has different arguments: 
accountService.create(
    [email protected] 
); 
-> at com.conf.controller.AccountController.registerNewAccount(AccountController.java:32) 

Argument(s) are different! Wanted: 
accountService.create(
    [email protected] 
); 
-> at com.conf.controller.AccountControllerSpec.registerNewUser(AccountControllerSpec.java:52) 
Actual invocation has different arguments: 
accountService.create(
    [email protected] 
); 
-> at com.conf.controller.AccountController.registerNewAccount(AccountController.java:32) 

    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) 
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) 
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) 
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423) 

私のコントローラクラス:

@Controller 
@RequestMapping(value = "/account") 
public class AccountController { 

    private AccountService accountService; 

    @Autowired 
    public AccountController(AccountService accountService){ 
     this.accountService = accountService; 
    } 

    @RequestMapping(value = "/register", method = RequestMethod.GET) 
    public String showRegistrationForm(){ 
     return "account/register"; 
    } 

    @RequestMapping(value = "/register", method = RequestMethod.POST) 
    public String registerNewAccount(Account account){ 
     accountService.create(account); 
     return "redirect:/"; 
    } 

} 

私のサービスクラス:

@Service 
@Transactional 
public class AccountService { 


    private AccountRepository repository; 

    @Autowired 
    public AccountService(AccountRepository repository) { 
     this.repository = repository; 
    } 

    public Account create(Account account){ 
     return repository.save(account); 
    } 
} 

マイリポジトリクラス:

@Component 
public interface AccountRepository extends CrudRepository<Account, Long>{ 

} 

そして、私のスペッククラス:

public class AccountControllerSpec { 

    private MockMvc mockMvc; 
    private AccountService service; 
    private AccountController controller; 

    @Before 
    public void before(){ 
     service = mock(AccountService.class); 
     controller = new AccountController(service); 
     mockMvc = standaloneSetup(controller).build(); 

    } 

    @Test 
    public void registrationPage() throws Exception { 
      mockMvc.perform(get("/account/register")).andExpect(view().name("account/register")); 
    } 

    @Test 
    public void registerNewAccount() throws Exception { 
     Account unsaved = new Account("M","B","[email protected]"); 
     Account saved = new Account("M","B","[email protected]"); 

     when(service.create(unsaved)).thenReturn(saved); 

      mockMvc.perform(post("/account/register") 
        .param("firstName","M") 
        .param("lastName","B") 
        .param("email","[email protected]")) 
        .andExpect(redirectedUrl("/")); 


     verify(service,atLeastOnce()).create(unsaved); 
    } 
} 

私は間違っていますか?

答えて

2

unsavedアカウントで私たちのコントローラがあなたのサービスに電話をかけられると期待しています。しかし、コントローラを呼び出すと、Springはリクエストで送信されたパラメータから新しいAccountインスタンスを作成し、そのアカウントでサービスを呼び出します。これはunsavedと等しくありません。

したがって、Springによって作成された実際のインスタンスがunsavedと等しくなるようにequals()およびhashCode()を定義するか、Accountを受け付ける別のマッチャーを使用するか、ArgumentCaptorを使用して渡された実際のアカウントを取得します。あなたのサービスをチェックし、期待される特性を持っていることを確認してください。

+0

他のマッチャーの例を教えてください。 – Ice

+0

'when(service.create(any)))then return(saved);' –

+0

'any()'を使って教えてもらえますか? @JB Nizet – Ice

関連する問題