I am new for Junit and Mockito and i am not understand how to write test case for below JdbcTemplate and i tried but getting exception ,Can some one help me please
org.mockito.exceptions.misusing.InvalidUseOfMatchersException:
Invalid use of argument matchers!
Code
#Repository
public class BaaisnEvcIdMSRepository {
#Autowired
private JdbcTemplate jdbcTemplate;
#Transactional
public RowMapperServerResponse getQueryEvcidRepository(BaaisnEvcIdRequest baaisnEvcIdRequest) {
RowMapperServerResponse rowMapperServerResponse = jdbcTemplate.queryForObject(
"select * from Master_Circuit WHERE master_ckt_id = ( select max(master_ckt_id) from master_circuit WHERE product = ? AND id_type = ?)",
new Object[]{baaisnEvcIdRequest.getProduct_type(),baaisnEvcIdRequest.getLata()}, new BaaisnRowMapper());
return rowMapperServerResponse;
}
}
test class
public class BaaisnEvcIdMSRepositoryTest {
#InjectMocks
BaaisnEvcIdMSRepository baaisnEvcIdMSRepository;
#Mock
JdbcTemplate jdbcTemplate;
#Before
public void setup() {
MockitoAnnotations.initMocks(this);
}
#Test
public void getQueryEvcidRepositoryTest() {
when(jdbcTemplate.queryForObject(eq(ArgumentMatchers.anyString()), refEq(new Object[]{ArgumentMatchers.anyInt()}), eq(String.class))).thenReturn("data");
verify(jdbcTemplate, times(1)).queryForObject(eq(ArgumentMatchers.anyString()), refEq(new Object[]{ArgumentMatchers.anyInt()}), eq(String.class));
}
}
The InvalidUseOfMatchersException is coming from your use of eq(ArgumentMatchers.anyString()) and refEq(new Object[]{ArgumentMatchers.anyInt()}). You are not supposed to wrap ArgumentMatchers inside anything else.
You also seem to aim at the wrong queryForObject method. It should be this one instead.
As mentioned before you need to call the method under test before doing the verification.
#Test
public void getQueryEvcidRepositoryTest() {
// use a real `BaaisnEvcIdRequest` object if you can
BaaisnEvcIdRequest req = Mockito.mock(BaaisnEvcIdRequest.class);
Mockito.when(req.getProduct_type()).thenReturn(1);
Mockito.when(req.getLata()).thenReturn(new Object());
Object[] array = new Object[]{req.getProduct_type(),req.getLata()};
Mockito.when(jdbcTemplate.queryForObject(Mockito.anyString(), Mockito.eq(array), Mockito.any(RowMapper.class)))
.thenReturn("data");
baaisnEvcIdMSRepository.getQueryEvcidRepository(req);
Mockito.verify(jdbcTemplate, Mockito.times(1))
.queryForObject(Mockito.anyString(), Mockito.eq(array), Mockito.any(RowMapper.class));
}
Related
It seems pass when a run the test individually but fine when fair when running the class .I have tried to use #Before and #After annotatoon.And only the Dirtiescontext most fit my case.My question is any alternative for dirtiescontext(too slow) or any method can suit my case?
My test code:
#SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
//#DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD)
#AutoConfigureMockMvc
class UserCoreControllerTest {
#Autowired
private UserRepository userRepository;
#Autowired
private UserCoreService userCoreService;
#Autowired
private ObjectMapper objectMapper;
#Autowired
private MockMvc mockMvc;
/*
*//* #BeforeTestMethod
public void setUp(){
System.out.println("begin");
userRepository.save(mockUser());
}
#AfterTestMethod
public void tearOff(){
System.out.println("end");
userRepository.deleteById(1);
}
*/
private User mockUser(){
User user= new User(0,"admin","admin",null,null,"yl","sd"
,"434","dsf",null,4,2,new ArrayList<>());
user.getApplications().add(mockJobOrder("job1title","b"));
user.getApplications().add(mockJobOrder("job2title","d"));
return user;
}
private JobOrder mockJobOrder(String title,String des){
return new JobOrder(0,1,title,des,null,null,0,2,false,0,null);
}
#Test
void getProfile() throws Exception {
userRepository.save(mockUser());
mockMvc.perform(get("/UserJob/getProfile/{id}", 1)
.accept(MediaType.APPLICATION_JSON_VALUE)
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.username")
.value("admin"))
.andDo(print());
}
#Test
void getUserByName() throws Exception {
userRepository.save(mockUser());
mockMvc.perform(get("/UserJob/get/Byusername/{username}", "admin")
.accept(MediaType.APPLICATION_JSON_VALUE)
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.password").value("admin"));
//if cant found user
MvcResult whatever = mockMvc.perform(get("/UserJob/get/Byusername/{username}", "whatever")
.accept(MediaType.APPLICATION_JSON_VALUE)
)
.andExpect(status().isOk())
.andReturn();
Assertions.assertEquals("",whatever.getResponse().getContentAsString());
}
#Test
void updateUser() throws Exception {
userRepository.save(mockUser());
User updated=new User(1,"alex","admin",null,null,"yl","sd"
,"434","dsf",null,4,2,null);
String request=objectMapper.writeValueAsString(updated);
MvcResult mvcResult=mockMvc.perform(MockMvcRequestBuilders.put("/UserJob/updateuser")
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON_VALUE)
.content(request)
)
.andExpect(status().isOk())
.andDo(print())
.andReturn();
Assertions.assertEquals("Successful update",mvcResult.getResponse().getContentAsString());
mockMvc.perform(get("/UserJob/getProfile/{id}", 1)
.accept(MediaType.APPLICATION_JSON_VALUE)
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.username")
.value("alex"))
.andDo(print());
}
#Test
void showApplicationshistory() throws Exception {
userRepository.save(mockUser());
mockMvc.perform(get("/UserJob/application/history/{id}", 1)
.accept(MediaType.APPLICATION_JSON_VALUE)
)
.andExpect(status().isOk())
.andExpect(jsonPath("$[0].title").value("job1title"))
.andExpect(jsonPath("$[1].title").value("job2title"))
.andDo(print());
}
#Test
void addUser() throws Exception {
User user=mockUser();
user.setUsername("tom");
String request=objectMapper.writeValueAsString(user);
mockMvc.perform(MockMvcRequestBuilders.post("/UserJob/add/user")
.contentType(MediaType.APPLICATION_JSON)
.content(request)
.accept(MediaType.APPLICATION_JSON_VALUE))
.andExpect(status().isOk())
.andExpect(jsonPath("$.username").value("tom"));
}
Application properties(i test it on a real database with drop-create)
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/test
spring.datasource.username=*
spring.datasource.password=*
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=create-drop
spring.jpa.defer-datasource-initialization=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
spring.sql.init.mode=always
logging.level.root=INFO
I guess that the test are failing because of some user constraints - since you insert the user a multiple times here.
There are multiple solutions for that.
Mark your test as transactional. The transaction is automatically rollbacked for tests.
Clear the tables manually after/before each test. Either by using the repository.deleteAll() or truncate the whole db with some sql statements.
Just as a side information: You can also use testcontainers instead of having a persistente database locally. See https://www.testcontainers.org/ or even better: a wrapper library around it: https://github.com/PlaytikaOSS/testcontainers-spring-boot
I am trying to Unit test the Resilience4j CircuitBreaker configuration for my service. But I am unable to call the fallback method when I throw HttpServerErrorException. However I try to mock the objects the call is not going to the fallback method.
The fallback works fine. When AService fails, the call is directed to fallback method calling BService. How do I write test cases to verify them?
I am new to Resilience4j and fallback patterns. Please help me to test this.
Service class
#AllArgsConstructor
#Service
public class ServiceImpl implements Service {
#NonNull
private AService aService;
#NonNull
private BService bService;
#CircuitBreaker(name = "resilienceConfig", fallbackMethod = "fallback")
#TimeLimiter(name = "resilienceConfig")
#Override
public Mono<List<PojoClass>> method(Mono<PojoClass2> pc) {
return pc
.map(PojoClass2::getPojoClass2)
.flatMapMany(Flux::fromIterable)
.map(Pojo3::getId)
.flatMap(service -> aService.method(param1, param2))
.flatMapMany(Flux::fromIterable)
.map(this::changeValues)
.collectList();
}
public Mono<List<PojoClass>> fallback(Mono<PojoClass2> pc, Throwable ex) {
return pc
.map(PojoClass2::getPojoClass2)
.flatMapMany(Flux::fromIterable)
.map(Pojo3::getId)
.flatMap(service -> bService.method(param1, param2))
.flatMapMany(Flux::fromIterable)
.map(this::changeValues)
.collectList();
}
}
ServiceTest
#SpringBootTest(classes = Application.class)
#RunWith(MockitoJUnitRunner.class)
public class ServiceImplTest {
#Mock
private AService aService;
#Mock
private BService bService;
#InjectMocks
ServiceImpl serviceImpl;
#Test
public void enrichException() {
doThrow(new HttpServerErrorException(HttpStatus.INTERNAL_SERVER_ERROR))
.when(aService)
.method(param1, param2);
Mono<List<PojoClass>> pojo = serviceImpl.method(param1);
}
}
I have been writing the test cases using the mockito. the below is my code in the test cases.
#RunWith(SpringRunner.class)
public class LoginControllerTest {
private MockMvc mockMvc;
#InjectMocks
private LoginService loginService;
#Mock
private LoginController loginController;
#Before
public void setup() {
MockitoAnnotations.initMocks(this);
// Setup Spring test in standalone mode
mockMvc = MockMvcBuilders.standaloneSetup(loginController).build();
}
#Test
public final void test() throws Exception {
// Assign
when(loginService.test()).thenReturn("hello");
// act
mockMvc.perform(get("/hello"))
// Assertion
.andExpect(status().isOk())
.andExpect(content().string("Message from service: hello"));
verify(loginService).test();
}
#Test
public final void usernameInvalidAndPassword() throws Exception {
User userData = new User();
userData.setUserName("akhila.s#cloudium.io");
userData.setPassword("Passw0rd");
User userDataNew = new User();
userDataNew.setUserName("akhila.s#cloudium.io");
userDataNew.setPassword("Passw0rd");
JSONObject requestBody = new JSONObject();
requestBody.put("userName", "akhila.s#cloudium.io");
requestBody.put("password", "Passw0rd");
JSONObject responseBody = new JSONObject();
responseBody.put("status_code", "200");
responseBody.put("message", "ok");
// Assign
when(loginService.saveUser(userData)).thenReturn(userDataNew);
// act
mockMvc.perform(get("/login")
.param("userName", "akhila.s#cloudium.io")
.param("password", "Passw0rd"))
// Assertion
.andExpect(status().isOk()).andExpect(content().json(responseBody.toString())).andDo(print());
}
For the first test case its working fine but for the second test it is returning null always. Can anyone please help? Thanks in advance
You have the annotations the wrong way round on your LoginController and LoginService. You are testing the controller so you don't want to mock it, and you are stubbing methods on your service so this needs to be a mock:
#Mock
private LoginService loginService;
#InjectMocks
private LoginController loginController;
In my opinion you have to either:
1) Introduce equals method based on username and password as the User object created inside the method under test is a different instance than the one you create and use in the test.
2) Use a wildcard in your set-up:
when(loginService.saveUser(Mockito.any(User.class))).thenReturn(userDataNew);
I'm trying to write a unit test for the code below where I instantiate a bean and pass it on to other private methods of the class for further processing before doing what the main method does:
public OverviewTabViewBean build(Listing listing) {
VehicleDetailListingBean vehicleDetailListingBean = new VehicleDetailListingBean();
applyVehicleDetailListingRules(listing, vehicleDetailListingBean);
OverviewTabViewBean overviewTabViewBean = new OverviewTabViewBean();
if (vehicleDetailListingBean != null) {
overviewTabViewBean.setMake(vehicleDetailListingBean.getMake());
overviewTabViewBean.setModel(vehicleDetailListingBean.getModel());
overviewTabViewBean.setAtCarId(vehicleDetailListingBean.getAtCarId());
..
}
return overviewTabViewBean;
private void applyCommonListingRules(Listing listing, VehicleDetailListingBean vehicleDetailListingBean) {
rulesEngineService.applyRules(listing, vehicleDetailListingBean, vehicleDetailRules.getCommonListingRules());
}
Test looks something like this:
#Captor
ArgumentCaptor<OverviewTabViewBean> overviewTabViewBean;
#Captor
ArgumentCaptor<VehicleDetailListingBean> vehicleDetailListingBean;
#Mock
private RulesEngineService rulesEngineService;
#Mock
private VehicleDetailRules vehicleDetailRules;
#Mock
private VehicleReferenceService vehicleReferenceService;
#BeforeMethod
public void setUp() {
MockitoAnnotations.initMocks(this);
}
/**
* build
*/
#Test
public void build() {
Listing listing = new Listing();
listing.setListingId(111L);
listing.setListingType(ListingType.NEW);
List<Rule<Listing, ListingBean>> rules1 = new ArrayList<Rule<Listing, ListingBean>>();
List<Rule<Listing, ListingBean>> rules2 = new ArrayList<Rule<Listing, ListingBean>>();
doReturn(rules1).when(vehicleDetailRules).getCommonListingRules();
doReturn(rules2).when(vehicleDetailRules).getDetailListingRules();
overviewTabViewBeanBuilder.build(listing);
verify(rulesEngineService, times(2)).applyRules(anyObject(), vehicleDetailListingBean.capture(), anyList());
.....
}
vehicleDetailListingBean is returning as null a not stepping into the if block. What am I doing wrong here?
I am trying to work with PowerMock, over Mockito; as I loved the API's for whennew() and verifyprivate() but i have some problem when trying to run testsuites with Categories TestRunner in Junit.
For using default JUnit test runners, I created a TestCase and added PowerMockRule as instance field with #Rule annotation. While execution of tests worked like this, ExpectedException TestRule is not working when used in conjunction
Example Code
#PowerMockIgnore ("*")
#PrepareForTest (CustomizedSSHConnection.class)
public class TestExpectedExceptionRule {
private Connection connection;
private ConnectionInfo connectionInfo;
#Rule
public PowerMockRule rule = new PowerMockRule ();
#Rule
public ExpectedException exception = ExpectedException.none ();
#Test
public void testExcepitonWithPowerMockRule() {
exception.expect (NullPointerException.class);
exception.expectMessage ("Image is null");
throw new NullPointerException ("Image is null");
}
}
Instead of using #Rule PowerMockRule if I use #RunWith(PowerMockRunner.class) this testcase will pass.
One other observation is if I annotate PowerMockRule with #ClassRule this succeeds but some of the mocking methods throwing exceptions.
PowerMock creates a deep clone of the TestExpectedExceptionRule object. Because of this it is running the test with a new ExpectedException rule, but you're calling exception.expect (NullPointerException.class) on the original rule. Hence the test fails, because the clone of the ExpectedException rule doesn't expect an exception.
Nevertheless there are at least two solutions for your problem.
RuleChain
Order the rules with JUnit's RuleChain. This needs some additional ugly code, but it works.
private ExpectedException exception = ExpectedException.none ();
private PowerMockRule powerMockRule = new PowerMockRule();
#Rule
public TestRule ruleChain = RuleChain.outerRule(new TestRule() {
#Override
public Statement apply(Statement base, Description description) {
return powerMockRule.apply(base, null, description);
}
}).around(exception);
Fishbowl
If you are using Java 8 then you can replace the ExpectedException rule with the Fishbowl library.
#Test
public void testExcepitonWithPowerMockRule() {
Throwable exception = exceptionThrownBy(
() -> throw new NullPointerException ("Image is null"));
assertEquals(NullPointerException.class, exception.getClass());
assertEquals("Image is null", exception.getMessage());
}
Without Java 8, you have to use an anonymous class.
#Test
public void fooTest() {
Throwable exception = exceptionThrownBy(new Statement() {
public void evaluate() throws Throwable {
throw new NullPointerException ("Image is null");
}
});
assertEquals(NullPointerException.class, exception.getClass());
assertEquals("Image is null", exception.getMessage());
}
I was able to fix this using the expected attribute in the #Test annotation. But the problem with this approach is that am unable to assert the exception message. Which is fine for me for now.
#PowerMockIgnore ("*")
#PrepareForTest (CustomizedSSHConnection.class)
public class TestExpectedExceptionRule {
private Connection connection;
private ConnectionInfo connectionInfo;
#Rule
public PowerMockRule rule = new PowerMockRule ();
#Rule
public ExpectedException exception = ExpectedException.none ();
#Test(expected = NullPointerException.class)
public void testExcepitonWithPowerMockRule() {
throw new NullPointerException ("Image is null");
}
}
I solved this problem by creating a PowerMockTestUtil class that uses a FunctionalInterface.
Utility class:
/**
* Utility class to provide some testing functionality that doesn't play well with Powermock out
* of the box. For example, #Rule doesn't work well with Powermock.
*/
public class PowerMockTestUtil {
public static void expectException(RunnableWithExceptions function, Class expectedClass, String expectedMessage) {
try {
function.run();
fail("Test did not generate expected exception of type " + expectedClass.getSimpleName());
} catch (Exception e) {
assertTrue(e.getClass().isAssignableFrom(expectedClass));
assertEquals(expectedMessage, e.getMessage());
}
}
#FunctionalInterface
public interface RunnableWithExceptions<E extends Exception> {
void run() throws E;
}
}
Sample test:
#Test
public void testValidateMissingQuantityForNewItem() throws Exception {
...
expectException(() -> catalogEntryAssociationImporter.validate(line),
ImportValidationException.class,
"Quantity is required for new associations");
}