2017-01-15 7 views
0

Ich erstelle meine erste Spring MVC, Boot, Daten Web-App und ich habe ein Problem, wenn ich Tests erstellen möchte. Ich modifiziere nur ein Beispiel aus Craig Walls Buch "Spring in Action". Ich habe versucht, TDD-Test für meinen Controller zu schreiben, für Methode registerNewAccount, ich war mir sicher, dass alles in Ordnung war, aber ich bekomme immer argumetns are different!. Voll-Stack-Trace:TDD Test für Spring MVC Controller funktioniert nicht richtig

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) 

Meine Controller-Klasse:

@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:/"; 
    } 

} 

Meine Service-Klasse:

@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); 
    } 
} 

Meine Repository Klasse:

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

} 

Und meine Spec Klasse:

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); 
    } 
} 

Was mache ich falsch?

Antwort

2

Sie erwarten von unserem Controller, dass er Ihren Dienst unter unsaved anruft. Wenn Sie jedoch Ihren Controller aufrufen, erstellt Spring eine neue Account-Instanz aus den in der Anfrage gesendeten Parametern und ruft den Service mit diesem Account auf, der ungleich unsaved ist.

Also definieren Sie entweder equals() und hashCode(), sodass die von Spring erstellte Instanz unsaved ist, oder verwenden Sie einen anderen Matcher, der ein Konto akzeptiert, oder verwenden Sie einen ArgumentCaptor, um das tatsächliche übergebene Konto zu erfassen Ihr Service und überprüfen Sie, ob es die erwarteten Eigenschaften hat.

+0

Können Sie mir ein Beispiel für andere Matcher geben? – Ice

+0

'when (service.create (any())). ThenReturn (gespeichert);' –

+0

Können Sie mir sagen, '' any() 'ist eine gute Idee? @JB Nizet – Ice

Verwandte Themen