I know how to write JUnit test case for findBySInvestigatorName(String SInvestigatorName) such method. But I want to know how to write test case for #Query method. Can any one please tell me how to write test case for following method?
#Repository
public interface InvestigatorRepository extends JpaRepository<Investigator, Integer> {
#Query("select new map(invest.sInvestigatorName as sInvestigatorName)"
+ " from Investigator invest where invest.nInstId=60")
Set<Investigator> findSinvestigatorName();
}
I tried like this
#RunWith(SpringRunner.class)
#DataJpaTest
public class TestInvestigatorRepository {
#Autowired
public TestEntityManager testEm;
#Autowired
InvestigatorRepository investRepo;
#Test
public void testFindSinvestigatorName() {
Investigator invest = new Investigator();
invest.setsInvestigatorName("abc");
invest.setnInstId(60);
Investigator saveInDb = testEm.merge(invest);
Set<Investigator> getFromDb = investRepo.findSinvestigatorName();
assertEquals(saveInDb.getsInvestigatorName(), getFromDb);
}
Test Failure
java.lang.AssertionError: expected:<abc> but was:<[{sInvestigatorName=abc}]>
at org.junit.Assert.fail(Assert.java:88)
at org.junit.Assert.failNotEquals(Assert.java:834)
at org.junit.Assert.assertEquals(Assert.java:118)
at org.junit.Assert.assertEquals(Assert.java:144)
Your test is almost fine, except that you compare a String with a Set<Investigator>.
Change your assertion to
assertEquals(saveInDb.getsInvestigatorName(), getFromDb.iterator().next().getsInvestigatorName());
Note: You might want to look into AssertJ. It allows you to write much nicer assertions for collections
Related
In the application I'm working now, I need to implement a few tests and build upon them. I've been reading and trying out a few things, but haven't had much success.
The goal is to start back-filling with tests the service layer of the application. The first one to be covered is UserService.
So, my idea is to assert the test user we use on the application returns itself. The test class so far is:
#RunWith(MockitoJUnitRunner.class)
#SpringBootTest(classes = {ApplicationMain.class})
public class UserServiceTest {
#Mock
CentralData dataProviderMock;
#InjectMocks
private UserService userService;
private <project>User testUser;
private <project>User mockUser;
#Before
public void init() {
MockitoAnnotations.initMocks(CentralData.class);
System.out.println("dataProviderMock: " + dataProviderMock);
System.out.println("userService: " + userService);
userService = new UserService(dataProviderMock);
testUser = createTestUser();
}
private <project>User createTestUser() {
testUser = new <project>User();
testUser.setSystemId("testuser");
testUser.setEmailAddress("testuser#system.com");
testUser.setFirstName("Test");
testUser.setLastName("User");
// save user
userService.save(testUser);
return testUser;
}
#Test
public void whenUserIdIsProvided_thenRetrievedNameIsCorrect() {
mockUser = userService.getUserById("testuser");
when(userService.getUser("testuser")).thenReturn(testUser);
assertEquals(testUser, mockUser);
}
}
On my UserService, I have this:
public UserService(CentralData dataProvider) {
this.dataProvider = dataProvider;
}
When I save the user, the mocked dataProviderMock logs to the console what I expect it to log. But on the test itself, the mockUser is always null.
I understand the userService does not really accesses the data layer and the database, so mockUser being null is not really wrong. So, how could I perform this test?
I'm pretty sure I'm missing something quite basic here, but can't really see it.
I'm using Mosby and I would like to test my simple presenter.
public class DetailsPresenter extends MvpBasePresenter<DetailsView> {
public void showCountry(Country country) {
getView().setTitle(country.getName());
getView().setFlag(country.getFlagUrl());
}
}
I've tried to solve it by mocking Presenter:
public class DetailsPresenterTest {
private DetailsPresenter mockPresenter;
private DetailsView mockView;
#Before
public void setUp() throws Exception {
mockPresenter = mock(DetailsPresenter.class);
mockView = mock(DetailsView.class);
when(mockPresenter.isViewAttached()).thenReturn(true);
when(mockPresenter.getView()).thenReturn(mockView);
doCallRealMethod().when(mockPresenter).showCountry(any(Country.class));
}
#Test
public void shouldShowFlag() throws Exception {
mockPresenter.showCountry(any(Country.class));
verify(mockView, times(1)).setFlag(anyString());
}
#Test
public void shouldShowName() throws Exception {
mockPresenter.showCountry(any(Country.class));
verify(mockView, times(1)).setTitle(anyString());
}
}
But I've got the error
Wanted but not invoked:
detailsView.setFlag(<any string>);
-> at eu.szwiec.countries.details.DetailsPresenterTest.shouldShowFlag(DetailsPresenterTest.java:39)
Actually, there were zero interactions with this mock.
I've tried to use also real presenter without a success.
you have to use real Presenter and a real country object to invoke showCountry(). Everything else doesnt make sense (not testing the real presenter but a mock presenter instance).
#Test
public void showFlagAndName(){
DetailsView mockView = mock(DetailsView.class);
DetailsPresenter presenter = new DetailsPresenter();
Country country = new Country("Italy", "italyFlag");
presenter.attachView(mockView);
presenter.showCountry(country);
verify(mockView, times(1)).showCountry("Italy");
verify(mockView, times(1)).setFlag("italyFlag");
}
Have you tried to add some logging to find out what's going on?
I think you do not hit the real method as
mockPresenter.showCountry(any(Country.class));
does not construct a Country object instance but simply passes null. So the condition
doCallRealMethod().when(mockPresenter).showCountry(any(Country.class));
is not met. If you use a less strict condition
doCallRealMethod().when(mockPresenter).showCountry(any());
you should get a NullPointerException.
You may solve this by using a real or a mocked Country instance on your method invocation.
Can I run a custom rule only for a particular test method in a test class?
public class TestClassExample
{
#Rule
public CustomRuleForOneEqualsOne customRuleForOneEqualsOne = new CustomRuleForOneEqualsOne();
#Test
public void test_OneEqualsOne()
{
assertEquals(1, 1);
}
#Test
public void test_TwoEqualsTwo()
{
assertEquals(2, 2);
}
}
In the above test class can I use my customRuleForOneEqualsOne rule be used only for test method test_OneEqualsOne and not for test_TwoEqualsTwo.
I've seen other solutions on Stack Overflow:
Move the two test methods into different class [say this option is not possible for particulr scenario] (or)
JUnit: #Before only for some test methods? as described by this post
I can somehow use the test method name and skip over the execution of the rule
but a drawback of this approach would be, each time I use the rule in a specific class for a specific set of methods, I need to add all those method names to a list to see if they are found, to determine the execution of the rest of the logic.
Is there any way to use a custom rule in a test class for a particular set of test methods while ignoring them for the other test methods in the same test class?
For the best of my knowledge, #Rule applies to all tests. Therefore, if you need #Rule to be used in a single #Test method only, don't use #Rule. In that case, your code would look like this:
public class TestClassExample {
#Test
public void test_OneEqualsOne() {
CustomRuleForOneEqualsOne customRuleForOneEqualsOne = new CustomRuleForOneEqualsOne();
// use customRuleForOneEqualsOne
}
#Test
public void test_TwoEqualsTwo() {
assertEquals(2, 2);
}
}
I am newe to Mockito and Junit, I have written unit test cases for testing my rest service and made use of Mockito for injecting mocks. And code is below:
BillControllerTest.java:
#RunWith(SpringJUnit4ClassRunner.class)
#SpringApplicationConfiguration(classes = Application.class)
#WebAppConfiguration
public class BillControllerTest{
private MockMvc mockMvc;
#Autowired
private WebApplicationContext webApplicationContext;
#InjectMocks
private BillController billController;
#Mock
private BillService mockBillService;
#Before
public void setupController() {
MockitoAnnotations.initMocks(this);
this.mockMvc = webAppContextSetup(webApplicationContext).build();
}
#Test
public void testBills() throws Exception {
// some fake data
final List<Bill> fakeBillList = new ArrayList<>();
fakeBillList.add(CpsFake.bill("1234"));
when(mockBillService.getBills(BILL_UID))
.thenReturn(fakeBillList.stream());
mockMvc.perform(get("/bills/" + BILL_UID ))
.andExpect(content().contentType(MediaTypes.HAL_JSON))
// expect particular uid
.andExpect(content().string(containsString("\"uid\":\"1234\"")))
ApplicationTest.java:
#RunWith(SpringJUnit4ClassRunner.class)
#SpringApplicationConfiguration(classes = Application.class)
#WebAppConfiguration
public class ApplicationTest {
#Test
public void contextLoads() {
}
}
BillController.java:
#RestController
#RequestMapping(value = "/trials/{billUid}", produces = "application/hal+json")
public class BillController extends BaseController {
#Autowired
private BillService billService;
#Autowired
public BillController(BillService billService) {
this.billService = billService;
}
#RequestMapping(method = RequestMethod.GET, value = "")
public ResponseEntity<Resources<Resource<Bill>>> getBills(#PathVariable String billUid) {
return resourceListResponseEntity(
() -> billService.getBills(billUid),
bill-> createResource(bill),
resources -> resources.add(linkTo(methodOn(BillController.class)
.getBills(billUid)).withSelfRel()));
}
When I run the test (BillControllerTest), mockBillService is not getting invoked and instead it is calling actual billService. Please help me in this issue. Thank you in advance.
I think the problem is that you use mockito together with spring. Both make use of proxys.
Looking at your code of getBills - it is not dependent on the spring application context. So skip all your spring setup code (mockMvc and webApplicationContext) and use only Mockito. If yet invisible code depends on the ApplicationContext - mock the application context rather than setting up a real one.
This test would be:
simpler
container independent
faster
You could replace initMocks with the Annotation RunWith(MockitoJUnitRunner.class) if you want.
I am using PowerMockito and jUnit to write unit test cases.
public class Foo {
private String resolveApplicationId() {
return "testApplication";
}
}
Here is my test case
#RunWith(PowerMockRunner.class)
#PrepareForTest(Foo.class)
public class test{
#Before
public void prepareTest() {
foo = PowerMockito.spy(new Foo());
}
#Test
public void checkApplicationIdIsResolved() throws Exception {
PowerMockito.doNothing().when(foo, "myPrivateMethod");
PowerMockito.verifyPrivate(foo).invoke("myPrivateMethod");
//Assert Here the returned value
}
}
Please tell me
1. how can I assert the value returned by the method when it is called
2. how can I call the private method
3. if not then what actually I verify when I write test case for private methods.
Thanks.
Testing private method does not differ from testing public method. If there is no external dependencies you even don't need to create and use any mocks. The only problem is with invocation of the private method from test. This is described here or you may use spring utils.
So you don't need to mock the method you are testing. You only require to mock other objects which are not tested in this particular test. So you test would look like
#Test
public void checkApplicationIdIsResolved() throws Exception {
// makeResolveIdAccessible();
// if needed setup mocks for objects used in resolveApplicationId
assertEquals(expectedApplicationId, foo.resolveApplicationId())
}