TDD test for Spring MVC controller not working correctly

Ice

I creating my first Spring MVC, Boot, Data web-app and I have a problem when I want to create tests. I just modify some example from Craig Wall book "Spring in Action". I tried to write TDD test for my controller, for method registerNewAccount, I was sure everything was ok, but all time I get argumetns are different!. Full stack trace below:

Argument(s) are different! Wanted:
accountService.create(
    com.conf.data.Account@2ed42a28
);
-> at com.conf.controller.AccountControllerSpec.registerNewUser(AccountControllerSpec.java:52)
Actual invocation has different arguments:
accountService.create(
    com.conf.data.Account@2a4d1467
);
-> at com.conf.controller.AccountController.registerNewAccount(AccountController.java:32)

Argument(s) are different! Wanted:
accountService.create(
    com.conf.data.Account@2ed42a28
);
-> at com.conf.controller.AccountControllerSpec.registerNewUser(AccountControllerSpec.java:52)
Actual invocation has different arguments:
accountService.create(
    com.conf.data.Account@2a4d1467
);
-> 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)

My Controller class:

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

}

My Service class:

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

My repository Class:

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

}

And my Spec Class:

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

What am I doing wrong?

JB Nizet

You expect our controller to call your service with the unsaved account. But when you invoke your controller, Spring creates a new Account instance from the parameters sent in the request, and invokes the service with that Account, which is not equal to unsaved.

So, either define equals() and hashCode(), so that the actual instance created by Spring is equal to unsaved, or use another matcher, which accepts any Account, or use an ArgumentCaptor to capture the actual Account passed by your service, and check that it has the expected properties.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

Spring MVC VersionResourceResolver / ContentVersionStrategy not working correctly in JSP

How to unit test a Spring MVC annotated controller?

How to test Spring MVC controller with pagination?

Spring MVC test post method with controller redirect

Using Spring security test to test a secured Spring MVC controller

Spring4 MVC Controller Pageable not working

set jquery date in spring mvc controller not working

MockHttpServletResponse has empty in test, despite Controller working correctly

Design MVC Controller using TDD for database calls

Spring Mvc test webapp @Autowired annotation is not working

Spring MVC Controller Request Mapping Does Not Work Correctly

While controller is not working correctly

Spring controller unit testing with spring-test-mvc is failing

Spring-Test-MVC / MockServletContext - content empty in test but working on Tomcat

Test if Hadoop is correctly working

MVC - Model not working correctly

How to unit test a ResponseBody or ResponseEntity sent by a spring mvc Controller?

spring boot - web mvc test does not find controller mapping

Best way to test Thymeleaf form / Spring MVC Controller interaction

Spring MVC controller Test - print the result JSON String

Is it a good practice to unit test controller classes in Spring MVC

Junit Test cases for Spring MVC controller to check @PathVariable parameters in @RequestMapping

How to unit test a Spring MVC controller using @PathVariable?

Mockito doesn't mock in spring mvc controller test

How to test Spring mvc controller tests for response entity?

Spring Boot Controller Test - Mockito when thenReturn list not working

Why isn't @Autowired working in my Spring MVC @Controller?

Domain types in Spring MVC controller method signatures not working

JsonView not working correctly with Spring