Hello every one I need to write unit tests for my methods. I'm having a bit of trouble because I'm new to JUnit. I need to write a test for this method.
this is my method
#Override
public Long countSellingOrdersInQueue(String principal) {
List<String> states = Arrays.asList(PENDING.name(), REGULARIZED.name());
return orderRepository.countByArticleUserIdAndStateIn(principal, states);
}
I try but i'm blocked and this is my result
P.S. test is passed but I don't understand if my test is true
#MockBean
private OrderRepository orderRepository;
private String principal ;
#Test
public void countSellingOrdersInQueueTest(){
orderService.countSellingOrdersInQueue(principal);
List<String> states = Arrays.asList(PENDING.name(), REGULARIZED.name());
orderRepository.countByUserIdAndStateIn(principal,states);
}
In your case, it is just the unit test, you need not use #MockBean, as it loads the context. Unit tests are meant to be run faster, using #MockBean, will load the context and takes time to complete the test. Here is the suggestion of when to use #Mock and when to use #MockBean.
As Maxim said, there were no assertions in the test. That was the reason why the tests weren't failing.
Few things to keep in mind while writing the test.
Tests are considered as documentation for the code, it should be more readable in such a way it makes others to understand the code.
As said before, unit tests are for giving faster feedback
Have AAA (Arrange, Act, Assert) structure in tests. More info here
Here is the code:
public class OrderServiceTest {
#InjectMocks
private OrderService orderService;
#Mock
private OrderRepository orderRepository;
#Before
public void setUp() throws Exception {
initMocks(this);
}
#Test
public void countSellingOrdersInQueueTest(){
when(orderRepository.countByArticleUserIdAndStateIn(any(), any())).thenReturn(1L);
String principal = "dummyString";
Long actualCount = orderService.countSellingOrdersInQueue(principal);
List<String> expectedStates = Arrays.asList("State 1", "State 2");
assertThat(actualCount, is(1L));
verify(orderRepository).countByArticleUserIdAndStateIn(principal, expectedStates);
}
}
Test passes because you don't have any assertion, which checks result. You just invoke methods which executes without exception.
Simple test example:
#Test
public void test() {
assertEquals(true, true);
}
In your case test will be look likes:
#Test
public void countSellingOrdersInQueueTest(){
orderService.countSellingOrdersInQueue(principal);
List<String> states = Arrays.asList(PENDING.name(), REGULARIZED.name());
orderRepository.countByUserIdAndStateIn(principal,states);
assertEquals(10, orderRepository.countByUserIdAndStateIn(principal,states));//10 replace to expectetion count
//add some more checks
}
Related
I have this junit:
#RunWith(MockitoJUnitRunner.class)
public class SecurityManagerServiceTest {
#Mock
private SecurityManagerService securityManagerService = mock(SecurityManagerService.class);
#Test
public void testRequireAll() {
when(securityManagerService.loggerUser()).thenReturn(fakeUser());
doCallRealMethod().when(securityManagerService).requireRight(anyString());
//given(securityManagerService.restoreRight("a")).willThrow(SecurityException.class);
when(securityManagerService.restoreRight("a")).thenThrow(SecurityException.class);
}
but I have this error:
unnecessary Mockito stubbings
I also tried:
#Mock
private SecurityManagerService securityManagerService = mock(SecurityManagerService.class);
#Test
public void testRequireAll() {
when(securityManagerService.loggerUser()).thenReturn(fakeUser());
doCallRealMethod().when(securityManagerService).requireRight(anyString());
given(securityManagerService.restoreRight("a")).willThrow(SecurityException.class);
}
The problem is that you are stubbing, but not really testing anything. And if you are not testing anything, then there is no need for stubbing. That's why you have unnecessary Mockito stubbings.
I assume that you want to test your SecurityManagerService. If you want to do that, you need to create an instance or have a bean of that type, but not a mock. Then you call the method that you want to test and assert that you get the expected result.
If you expect to get an exception you can test it like this:
JUnit4, just enhance you #Test annotation:
#Test(expected=SecurityException.class)
JUnit 5:
#Test
void testExpectedException() {
Assertions.assertThrows(SecurityException.class, () -> {
//Code under test
});
}
Is this the correct essence of unit testing? I think i don't understand what should I test. ConverterContext is a strategy class
#SpringBootTest
#ExtendWith(SpringExtension.class)
class ConverterContextTest {
#Autowired
private final ConverterContext converterContext;
#Autowired
private final ConverterRegisterUserDto created;
#Autowired
ConverterContextTest(ConverterContext converterContext, ConverterRegisterUserDto created) {
this.converterContext = converterContext;
this.created = created;
}
#Test
void converterContextGivesCorrectConverter(){
ConverterRegisterUserDto returned = converterContext.getConverter(ConverterRegisterUserDto.class);
assertEquals(returned, created);
}
#Test
void converterContextGivesIncorrectConverter(){
ConverterShowUserDto returned = converterContext.getConverter(ConverterShowUserDto.class);
assertNotEquals(returned, created);
}
}
In a unit test, you want to avoid loading a spring boot context. So instantiate yourself ConverterContext.
If ConverterContext has some dependencies that you need to isolate, you can mock them (see the Mockito library).
Besides you should not need either to autowire the expected.
It will make your test faster to execute and simpler to read.
Note that in your code ConverterContext appears as a factory and not a strategy.
About the logic of your test, I think that the second test is not required.
What you want to check is that the factory returns what it is designed to return.
Asserting that the actual is not equal to a dumb expected is perfectly useless . It is like dead code that you have to main...
In fact, it is like if you asserted that add(1,1) == 2 in the first test and that in the second test you asserted that add(2,1) != 2.
Why not assert that all dumb expected are not equal ?
add(2,1) != 4, add(2,1) != 5, add(2,1) != 6, and we can go on a very long time....
I would expect a unit test that looks like (I used JUnit 5 way to illustrate) :
import org.mockito.junit.jupiter.MockitoExtension;
import org.mockito.Mock;
import org.junit.jupiter.api.extension.ExtendWith;
#ExtendWith(MockitoExtension.class)
class ConverterContextTest {
ConverterContext converterContext;
#Mock
FooDep fooDep;
#Mock
BarDep barDep;
#BeforeEach // or #Before in JUnit 4
void init{
converterContext = new ConverterContext(fooDep, barDep);
}
#Test
void converterContextGivesCorrectConverter(){
// mock which is required
/...
assertEquals(new ConverterRegisterUserDto(), converterContext.getConverter(ConverterRegisterUserDto.class));
// mock which is required
/...
assertEquals(new ConverterShowUserDto(), converterContext.getConverter(ConverterShowUserDto.class));
}
}
With unit testing the idea is to test the smallest possible piece of code. In most cases this means a class and what its methods do. As for how many tests to write, that really depends on the person. To give an example:
public class Point2D
{
private int x, y;
public Point2D() {this.x = 0; this,y = 0;}
public int getX() {return x;}
public int getY() {return y;}
}
class Point2DTest
{
#Autowired
private final Point2D p;
#Test
void getXReturnsZero()
{
int expected = 0;
assertEquals(expected, p.getX());
}
#Test
void getYReturnsZero()
{
int expected = 0;
assertEquals(expected, p.getY());
}
#Test
void getXDoesNotReturnZero()
{
int expected = 1;
assertNotEquals(expected, p.getX());
}
#Test
void getYDoesNotReturnZero()
{
int expected = 1;
assertNotEquals(expected, p.getY());
}
}
This test could have been left with the first two methods, but for more test coverage a person may test more. I think its important to note that exhaustive testing (testing every possible outcome) is impossible in real life scenarios and generally a cut off point will be defined.
I tend to think of it as more of an integration test when you're loading a Spring context and more of a unit test when you don't and you're testing a specific logic of a small method without any context. When you're trying to test a class that only realistically depends on other injected beans in a Spring context you can use a framework like Mockito in order to keep them unit tests and prevent them from becoming full blown integration tests. I hope that's helpful.
I have such method in my service layer:
public Long calculateItemsCostInShoppingCart(Long shoppingCartId) {
List<Item> items = shoppingCartRepository.findAllItems(shoppingCartId);
Long cost = 0L;
for (Item item : items) {
cost += item.getPrice();
}
return cost;
}
And I need to test calculation of summary cost of all items in list. I was thought about mockito, but it didn't work out cause mockito just create stubs, I need real entrance data and result based on them. How can do it?
// create mock
ShoppingRepository mock = mock(ShoppingRepository.class);
// define return value for method findAllItems()
when(mock.findAllItems()).thenReturn(listOf(...));
Here is an example how you can test it with Mockito:
public class SomeCalculatorTest {
#Mock
private ShoppingCartRepository shoppingCartRepository;
#InjectMocks
private SomeCalculator someCalculator = new SomeCalculator();
#Before
public void setUp() {
initMocks(this);
}
#Test
public void testEmptyItemsList() {
when(shoppingCartRepository.findAllItems(any())).thenReturn(new ArrayList<>());
final Long result = someCalculator.calculateItemsCostInShoppingCart(1L);
assertThat(result, is(0L));
}
#Test
public void testOneItemInList() {
when(shoppingCartRepository.findAllItems(any())).thenReturn(Arrays.asList(new ItemImpl(25L)));
final Long result = someCalculator.calculateItemsCostInShoppingCart(1L);
assertThat(result, is(25L));
}
#Test
public void testTwoItemInList() {
when(shoppingCartRepository.findAllItems(any())).thenReturn(Arrays.asList(new ItemImpl(25L), new ItemImpl(12L)));
final Long result = someCalculator.calculateItemsCostInShoppingCart(1L);
assertThat(result, is(37L));
}
}
Assuming that you are developing a Java web application which runs on a application server another option might be to use Arquillian (http://arquillian.org/). In a nutshell, Arquillian is a framework which allows you to test you logic in environment it will run. But it might be some work to integrate Arquillian into your project. We are using Arquillian in several projects and it works well so far. Even the Persistence module which is an Alpha version works well.
And I need to test calculation of summary cost of all items in list.
In this case, you have to isolate the shoppingCartRepository dependency that doesn't perform any calculation.
I need real entrance data and result based on them. How can do it?
It describes an integration test. In this case, don't use Mockito.
To unit test :
You have to mock the dependency and you also need a way to set it in the instance of the class under test.
A constructor is often a fine way (let calling the class under test MyService):
public MyService(ShoppingCartRepository shoppingCartRepository){
this.shoppingCartRepository = shoppingCartRepository;
}
Then, in the test you should mock ShoppingCartRepository, record a behavior for findAllItems() and pass the mock in the constructor of MyService.
#Mock
private ShoppingCartRepository shoppingCartRepositoryMock;
#Test
public void calculateItemsCostInShoppingCart(){
Long cartId = Long.valueOf(123);
// set the dependency
MyService myService = new MyService(shoppingCartRepositoryMock);
// create the mock
Mockito.when(shoppingCartRepositoryMock.findAllItems(cartId))
.thenReturn(createMockedItems());
//action
Long actualCost = myService.calculateItemsCostInShoppingCart(cartId);
// assertion
Assert.assertEquals(expectedCost, actualCost);
}
private List<Item> createMockedItems() { ... }
You can use Rest assured library for test
get Rest assured response Object, and call method for method object of list.
#BeforeClass
public static void init() {
RestAssured.baseURI = "http://localhost";
RestAssured.port = 8080;
}
#Test
public void testUserRegistration() {
Response response =
RestAssured
.given()
.get(URL_LOGIN)
.then()
.assertThat()
.statusCode(200);
Assert.assertThat(200, Matchers.is(200));
Assert.assertThat(response.getStatusCode(), Matchers.is(200));
}
we are developing an application using spring mvc framework. I have given all the classes below, please suggest how to write a junit test case for the below scenario.
I want to write a junit test case for the validateAccountInformation(requestDTO) method which is called in validateAccount(..) method of LPAValidator.java class. Below is my junit test case followed by the java classes. Actual call goes from the LPAController.java as shown in the below code.
LPAControllerTest.java
#Test(groups = "manual")
public void submitRequestForLPAAccountTest()
{
// businessCalendar.nextBusinessDay(
// LocalDateHelper.today(), LPAConstants.TWENTY_BUSSINESS_DAYS)
//i want to write the test case for the above commented logic,
//if business days is not equal to twenty days, test should fail.
}
LPAController.java
#RequestMapping(value = "/lpa/{accNumber}/spread, method = RequestMethod.GET)
public #ResponseBody LPAResponseDTO accountSearch(#RequestBody final LPARequestDTO clientrequestBody,
#PathVariable final String accNumber, final HttpServletResponse response)
{
//some logic goes here
final LPAAccountResponse domainResponse = service.submitRequestForLPAAccount(requestBody);
}
LPAServiceImpl.java
#PermitAll
#NonTransactional
public LPAResponse submitRequestForLPAAccount(final LPARequest requestDTO)
{
return lpaRepository.submitRequestForLPAAccount(requestDTO));
}
LPARepository.java
#PermitAll
#NonTransactional
public LPAResponse submitRequestForLPAAccount(final LPARequest requestDTO)
{
//some logic
lpaValidator.validateAccount(requestDTO);
//some logic
}
LPAValidator.java -- java class for validations
#component
class LPAValidator{
#Inject
private BusinessCalendar businessCalendar;
void validateAccount(final LPARequest requestDTO) throws Exception {
try {
validateAccountInformation(requestDTO);
} catch(Exception e){
}
}
private void validateAccountInformation(final LPARequest requestDTO) throws Exception{
final accDate lpaAccDate = requestDTO.getLPADate();
final LocalDate twentyBussinessDays = businessCalendar.nextBusinessDay(
LocalDateHelper.today(), LPAConstants.TWENTY_BUSSINESS_DAYS); //i want to write
//test case for this line of code, if business days given is more than twenty test should fail.
//some logic here
}
Please suggest what needs to be added in LPAControllerTest.java to test the nextBusinessDay(..) as discussed above.
You're trying to write an integration test in which your controller is called, which then calls all the subclasses until the validator is triggered. That is not a traditional 'unit test'.
A traditional unit test would just test the validator straight up, and nothing more.
Nevertheless, when writing an integration test, spring documentation to the rescue
In short, it'll require you to create an applicationcontext with all the necessary scaffolding, and then use a mockMvc call to do a GET on the created application.
If you want to test the validator, use simple mocking framework:
See [http://mockito.org]
Gives you something like this:
#Mock BusinessCalendar businessCalendarMock;
#Mock LPARequest mockRequest;
#Mock accDate mockDate;
#Mock LocalDate mockLocalDate;
#InjectMocks LPAValidator lpaValidator = new LPAValidator();
#Test public void testValidateAccount() {
when(mockRequest.getLPAdate()).thenReturn(mockDate);
when(businessCalendar.nextBusinessDay(LocalDateHelper.today(),LPAConstants.TWENTY_BUSSINESS_DAYS).thenReturn(mockLocalDate);
// continue your test from here
lpaValidator.validateAccount( mockRequest);
verify(businessCalendar).nextBusinessDay(LocalDateHelper.today(),LPAConstants.TWENTY_BUSSINESS_DAYS);
// although if the use of mockLocalDate is integral to your code, it'll probably show before and no verify is necessary;
I was playing with org.springframework.data.jpa.domain.Specifications, it's just a basic search :
public Optional<List<Article>> rechercheArticle(String code, String libelle) {
List<Article> result = null;
if(StringUtils.isNotEmpty(code) && StringUtils.isNotEmpty(libelle)){
result = articleRepository.findAll(Specifications.where(ArticleSpecifications.egaliteCode(code)).and(ArticleSpecifications.egaliteLibelle(libelle)));
}else{
if(StringUtils.isNotEmpty(code)){
result= articleRepository.findAll(Specifications.where(ArticleSpecifications.egaliteCode(code)));
}else{
result = articleRepository.findAll(Specifications.where(ArticleSpecifications.egaliteLibelle(libelle)));
}
}
if(result.isEmpty()){
return Optional.empty();
}else{
return Optional.of(result);
}
}
And that's actually working fine but I'd like to write unit tests for this method and I can't figure out how to check specifications passed to my articleRepository.findAll()
At the moment my unit test looks like :
#Test
public void rechercheArticle_okTousCriteres() throws FacturationServiceException {
String code = "code";
String libelle = "libelle";
List<Article> articles = new ArrayList<>();
Article a1 = new Article();
articles.add(a1);
Mockito.when(articleRepository.findAll(Mockito.any(Specifications.class))).thenReturn(articles);
Optional<List<Article>> result = articleManager.rechercheArticle(code, libelle);
Assert.assertTrue(result.isPresent());
//ArgumentCaptor<Specifications> argument = ArgumentCaptor.forClass(Specifications.class);
Mockito.verify(articleRepository).findAll(Specifications.where(ArticleSpecifications.egaliteCode(code)).and(ArticleSpecifications.egaliteLibelle(libelle)));
//argument.getValue().toPredicate(root, query, builder);
}
Any idea?
I was having almost the same problems as you had, and I changed my class that contains Specifications to be an object instead of just one class with static methods. This way I can easily mock it, use dependency injection to pass it, and test which methods were called (without using PowerMockito to mock static methods).
If you wanna do like I did, I recommend you to test the correctness of specifications with integration tests, and for the rest, just if the right method was called.
For example:
public class CdrSpecs {
public Specification<Cdr> calledBetween(LocalDateTime start, LocalDateTime end) {
return (root, query, cb) -> cb.between(root.get(Cdr_.callDate), start, end);
}
}
Then you have an integration test for this method, which will test whether the method is right or not:
#RunWith(SpringRunner.class)
#DataJpaTest
#Sql("/cdr-test-data.sql")
public class CdrIntegrationTest {
#Autowired
private CdrRepository cdrRepository;
private CdrSpecs specs = new CdrSpecs();
#Test
public void findByPeriod() throws Exception {
LocalDateTime today = LocalDateTime.now();
LocalDateTime firstDayOfMonth = today.with(TemporalAdjusters.firstDayOfMonth());
LocalDateTime lastDayOfMonth = today.with(TemporalAdjusters.lastDayOfMonth());
List<Cdr> cdrList = cdrRepository.findAll(specs.calledBetween(firstDayOfMonth, lastDayOfMonth));
assertThat(cdrList).isNotEmpty().hasSize(2);
}
And now when you wanna unit test other components, you can test like this, for example:
#RunWith(JUnit4.class)
public class CdrSearchServiceTest {
#Mock
private CdrSpecs specs;
#Mock
private CdrRepository repo;
private CdrSearchService searchService;
#Before
public void setUp() throws Exception {
initMocks(this);
searchService = new CdrSearchService(repo, specs);
}
#Test
public void testSearch() throws Exception {
// some code here that interact with searchService
verify(specs).calledBetween(any(LocalDateTime.class), any(LocalDateTime.class));
// and you can verify any other method of specs that should have been called
}
And of course, inside the Service you can still use the where and and static methods of Specifications class.
I hope this can help you.
If you are writing Unit Tests then you should probably mock the call to findAll() method of articleRepository Class using a mocking framework like Mockito or PowerMock.
There is a method verify() using which you can check if the mock is invoked for the particular parameters.
For Example, if you are mocking the findAll() method of articleRepository Class and want to know if this method is called with particular arguments then you can do something like:
Mokito.verify(mymock, Mockito.times(1)).findAll(/* Provide Arguments */);
This will fail the test if mock has not been called for the arguments that you provided.
Your problem is that you are doing too many things within that one method. You should have three different methods that work on articleRepository.
Then you can use mocking as the others suggest:
setup your mocks so that you know which call on articleRepository should be made
verify that exactly the expected calls are happening
Please note: these three methods should be internal; the main point there is: you can't test this method with ONE call from the outside; as it is doing more than one thing, depending on the input that you provide. Thus you need to create at least one test method for each of the potential paths in your code. And that becomes easier (from a conceptual point of view) when you separate your code into different methods.