Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Geting java.lang.IllegalStateException: Duplicate mock definition while using @MockBean in test case

Tags:

java-8

I have one service class that I want to mock but while running the test I am Getting Caused by: java.lang.IllegalStateException: Duplicate mock definition [MockDefinition@482ba4b1 name = '', typeToMock = com.service.ThirdPartyService, extraInterfaces = set[[empty]], answer = RETURNS_DEFAULTS, serializable = false, reset = AFTER]

I have tried to create mock service using @MockBean at class level, field level, and used @Qualifier as well to resolve the issue

@Service
public class ThirdPartyService{

.......................

    public String decrypt(String encryptedText) { 
    //third party SDK I am using
        return Service.decrypt.apply(encryptedText);
    }
.........
..............
}


    @ComponentScan("com")
    @PropertySource({"classpath:/api.properties", "classpath:/common.properties"})
    @SpringBootConfiguration
    @RunWith(SpringRunner.class)
    @SpringBootTest(classes = {Application.class}, webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
    @Transactional
    public class TestControllerTest extends IntegrationTest {
    @MockBean
    ThirdPartyService thirdPartyService;
    @Before
    public void initMocks(){
    MockitoAnnotations.initMocks(this);
    }

    @Test
    public void test() throws Exception {
    when(ts.decrypt("encryptedText")).thenReturn("decryptedText")    
    Request req = Request.builder().name("name123").build();
    //written performPost method in some other class
    ResultActions action = performPost("/test", req);
    action.andExpect(status().isOk());  
    }
    }

    public class IntegrationTest {
    protected final Gson mapper = new Gson();
    private MockMvc mvc;
    @Autowired
    private WebApplicationContext context;
    public ObjectMapper objectMapper = new ObjectMapper();
    @Before
    public void setup() {
    this.mvc = MockMvcBuilders.webAppContextSetup(context).apply(springSecurity()).build();
    }}

When I am calling Thirdparty service decrypt method then it should return me decryptedText as a string. But getting duplicate mock definition error

like image 698
Coder Avatar asked Oct 30 '19 09:10

Coder


2 Answers

I had the same issue. Cause of this were test configuration file which was put somewhere else and it contained the mocked bean.

I have solved this by using @Autowired instead of @MockBean as this will result in autowiring the already mocked bean.

like image 175
convexmethod Avatar answered Sep 22 '22 08:09

convexmethod


In my case the problem appeared after another dependency update and the reason was in the @SpringBootTest annotation referencing the same class twice:

@SpringBootTest(classes = {MyApplication.class, ApiControllerIT.class})
class ApiControllerIT extends IntegrationTestConfigurer {
    // ...
}
@SpringBootTest(classes = {MyApplication.class, TestRestTemplateConfiguration.class})
public class IntegrationTestConfigurer {
    // ...
}

I fixed it by removing @SpringBootTest annotation from the child class (ApiControllerIT).

like image 21
polarfish Avatar answered Sep 22 '22 08:09

polarfish