-1

I have a category entity with a unique field "name".

I'm using a custom unique annotation to validate the data and it works perfectly.

I'm trying to test my controller on my spring boot application and i want to check if the the request returns a 400 status if the data is duplicated ( unique name ).

in postman it works as expected and returns the 400 status with the errors list.

with unit testing, it returns a 201 status with an empty body ( but in reality, returning a 201 means that the body contains the new created entity! )

this is my test:

    @Test
    public void testIfAdminCanCreateCategory_expect400BecauseCategoryAlreadyExist() throws Exception {
        // json
        String data = "{\"name\" : \"CATEGORY\"}";
        mockMvc().with(keycloakAuthenticationToken().authorities("ROLE_admin")).perform(post("/categories").content(data).contentType("application/json"))
                .andDo(print())
                .andDo(r -> mockMvc().with(keycloakAuthenticationToken().authorities("ROLE_admin"))
                        .perform(post("/categories").content(data).contentType("application/json"))
                        .andExpect(status().isBadRequest()));
    }

my controller:

    @PostMapping
    @PreAuthorize("hasRole('ROLE_admin')")
    public HttpEntity<MainCategory> create(@Valid @RequestBody CreateMainCategory createMainCategory)
    {
        return ResponseEntity.status(HttpStatus.CREATED).body(mainCategoryService.create(createMainCategory));
    }

my service:

    @Override
    public MainCategory create(CreateMainCategory createMainCategory) {
        MainCategory mainCategory = new MainCategory();
        mainCategory.setName(createMainCategory.getName().toUpperCase());
        return mainCategoryRepository.save(mainCategory);
    }

my entity:

@Entity
@EntityListeners( AuditingEntityListener.class  )
@Data
public class MainCategory {

    @Id @GeneratedValue private Long id;

    private String name;

    @CreatedBy
    private String createdBy;

    @OneToMany(cascade = CascadeType.REMOVE, mappedBy = "mainCategory")
    List<Category> categories;
}

the request from logs:

MockHttpServletRequest:
      HTTP Method = POST
      Request URI = /categories
       Parameters = {}
          Headers = [Content-Type:"application/json;charset=UTF-8", Content-Length:"21"]
             Body = {"name" : "CATEGORY"}
    Session Attrs = {SPRING_SECURITY_CONTEXT=org.springframework.security.core.context.SecurityContextImpl@6989924: Authentication: org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken@6989924: Principal: user; Credentials: [PROTECTED]; Authenticated: true; Details: org.keycloak.adapters.springsecurity.account.SimpleKeycloakAccount@40fd518f; Granted Authorities: ROLE_admin}

the response from logs:

MockHttpServletResponse:
           Status = 201
    Error message = null
          Headers = [Vary:"Origin", "Access-Control-Request-Method", "Access-Control-Request-Headers", X-Content-Type-Options:"nosniff", X-XSS-Protection:"1; mode=block", Cache-Control:"no-cache, no-store, max-age=0, must-revalidate", Pragma:"no-cache", Expires:"0", X-Frame-Options:"DENY"]
     Content type = null
             Body = 
    Forwarded URL = null
   Redirected URL = null
          Cookies = []

java.lang.AssertionError: Status 
Expected :400
Actual   :201
Djellal Mohamed Aniss
  • 1,723
  • 11
  • 24
  • have a look here [how-to-test-if-valid-annotation-is-working](https://stackoverflow.com/questions/38081086/how-to-test-if-valid-annotation-is-working?noredirect=1&lq=1) – Dirk Deyne Aug 15 '20 at 18:35

2 Answers2

0

the problem was related to the save() method, it wasn't saving any entity even when defining a mysql database on my properties file ( which explains the empty body in the 201 created status ).

a solution is to use a H2 database for testing, adding it's configuration in a separate properties file ( in my case product-service-test.yml ) and add @ActiveProfiles("test") to the test class.

Djellal Mohamed Aniss
  • 1,723
  • 11
  • 24
-1

In the test case, it is nowhere showing that data is duplicate. You are defining String data inside test case and consuming it there. Hence it gives 200 created status.

In entity creation, name is not defined unique.

@Column(unique=true)
private String name;

By default it is false.

S Khandelwal
  • 199
  • 2
  • 13