Java unit test mock a method with predicate as an argument - java-8

I have two classes:
ClassA {
public String methodA(String accountId, Predicate<User> predicate) {
// more code
};
}
ClassB {
methodB(){
ClassA objectA = new ClassA();
objectA.methodA("some id", PredicatesProvider.isUserValid());
// more code ...
}
}
class PredicatesProvider {
static Predicate<User> isUserValid(){
return (user) -> {
return user.isValid();
}
}
In my unit test, I need to mock ClassA, so I use Mockito's mock method like the following:
ClassA mockObjectA = Mockito.mock(ClassA.class);
Mockito.when(mockObjectA).methodA("some id", PredicatesProvider.isUserValid()).thenReturn("something");
Mockito couldn't find a signature match.
The java.lang.AssertionError: expected:<PredicatesProvider$$Lambda$5/18242360#815b41f> but was:<PredicatesProvider$$Lambda$5/18242360#5542c4ed>
This is kind of a simplified version of what I am trying to achieve. I guess this is a problem with the equals() function of predicate. Any idea how to mock a method that has a predicate argument?
Thanks

I see 4 possible solutions:
Always return the exact same Predicate instance from your isUserValid() method. Since the Predicate is stateless, that's not a problem.
Implement the Predicate as a real class, implementing equals() and hashCode(). But that's overkill compared to the first solution.
Use a matcher:
Mockito.when(mockObjectA).methodA(Mockito.eq("some id"), Mockito.<Predicate<User>>anyObject()).thenReturn("something");
Don't use a static method to create the predicate, but an injectable Factory, that you can mock and verify:
PredicatesProvider mockPredicatesProvider = mock(PredicatesProvider.class);
Predicate<User> expectedPredicate = (u -> true);
when(mockPredicatesProvider.isUserValid()).thenReturn(expectedPredicate);
when(mockObjectA).methodA("some id", expectedPredicate).thenReturn("something");

Related

Can this method be tested using mockito?

I am not sure how to test the first method in the service layer with Mockito as it is using the helper method. Below is my failed attempt at a test: I get an InvalidUseOfMatchersException in the second when clause.
Thanks in advance!
#Mock
private EntityRepository EntityRepo;
#InjectMocks
private EntityService EntityService;
public List<DTO> getAllDTOs(){
//first method
return entityRepo.findAll()
.stream()
.map(this::convertEntityToDTO)
.collect(Collectors.toList());
}
//helper method
public DTO convertEntityToDTO(Entity entity) {
ModelMapper modelMapper = new ModelMapper();
modelMapper.getConfiguration()
.setMatchingStrategy(MatchingStrategies.LOOSE);
DTO dto = new DTO();
dto = modelMapper.map(entity, DTO.class);
return dto;
}
#Test
public void EntityService_GetAll_ReturnsDTOList() {
when(entityRepo.findAll()).thenReturn(Mockito.anyList());
//the second when clause: when(entityService.convertEntityToDTO(Mockito.any(Entity.class)))
.thenReturn(Mockito.any(DTO.class));
List<DTO>DTOList = entityService.getAllDTOs();
Assertions.assertThat(DTOList).isNotNull();
Mockito#any* methods are actually defined in class ArgumentMatchers and can only be used to match the call arguments when setting up a mock or when verifying calls. All matcher methods return null (but have side-effects of modifying a matcher stack to be able to properly detect and match mocked calls).
For instance, you might do Mockito.when(svc.print(Mockito.anyString()).doNothing() when you don't care about the input or Mockito.verify(svc.print(Mockito.anyString()), Mockito.never()) when you want to verify that the method has never been called.
When setting up your mock, you have to provide a real value in your thenReturn call:
when(entityRepo.findAll()).thenReturn(Collections.emptyList());
when(entityService.convertEntityToDTO(Mockito.any(Entity.class)))
.thenReturn(new DTO());

How to mock a particular method of a spring bean

I have a spring bean with multiple APIs. Mocking the bean doesn't serve my purpose as I would like to verify fetchFromDb() called only once on multiple calls to getCachedData() with the same input. This is to make sure the result is cached.
Is it possible to mock fetchFromDb() on bean 'market' while calling getCachedData()?
Sample Class
#Configuration("market")
public class AllMarket {
#Autowired
private CacheManager cachedData;
public boolean getCachedData(LocalDate giveDate) {
//check if it exists in cache
if(Objects.nonNull(checkCache(giveDate)) {
return checkCache(giveDate);
}
//fetch from database
boolean bool = fetchFromDb(givenDate);
cacheData(giveDate, bool);
return bool;
}
public boolean checkCache(LocalDate giveDate) {
return cacheManager.getData(givenDate);
}
public boolean fetchFromDb(LocalDate givenDate) {
//return the data from database
}
public void cacheData(LocalDate givenDate, boolean bool) {
cacheManager.addToCache(givenDate, bool);
}
}
You can use Mockito.spy() for this kind of test. In this case you should spy your AllMarket instance and stub fetchFromDb. At the end you can Mockito.verify that fetchFromDb was called exactly once. It will look something like this:
AllMarket spy = spy(allMarket);
when(spy.fetchFromDb(givenDate)).thenReturn(true); //you have boolean as a return type
...
verify(spy, times(1)).fetchFromDb(givenDate);
For more information, you can see Official Mockito doc
Maybe mockito argument captor could asist you. It lets you to capture method input and how many times method was called, also may other functions. Please check https://www.baeldung.com/mockito-annotations.

Test case for constructor as i have a filter logic

I have constructor where there is filter logic and wanna test it, though writing test case for constructor is not in practice i wanna have the code coverage , have tried many links but none are explaining about handling a constructor.
public Myclass {
public Myclass(AnotherClass obj)
{
_key = obj.key;
_ID = obj.ID;
_CandidateMode = obj.CandidateMode;
if(_CandidateMode == obj.CandidateMode.numeric
{
//Dosomething
}
else
{
//Do something with special character.
}
}
}
Definitely placing logic inside a constructor is a thing to avoid. Good you know that :-) In this particular case maybe the if could go into each of the public methods of MyClass, or maybe you could use polymorphism (create MyClass or MySpecialCharacterClass base on the AnotherClass object)?
Anyway, to get to a straight answer: if you really must test constructor logic, do it like you would test any other method (in some languages it's just a static method called new, by the way).
[TestMethod]
public void is_constructed_with_numeric_candidate() {
// Given
AnotherClass obj = new AnotherClass { CandidateMode = CandidateMode.numeric };
// When
MyClass myClass = new MyClass(obj);
// Then
// assert myClass object state is correct for numeric candidate
...
}
[TestMethod]
public void is_constructed_with_special_candidate() {
// Given
AnotherClass obj = new AnotherClass { CandidateMode = CandidateMode.special };
// When
MyClass myClass = new MyClass(obj);
// Then
// assert myClass object state is correct for special candidate
...
}

java 8 - how abstracts the use of predicates by using methods

I am trying to create a class that abstracts the use of predicates from its end user.
My app uses Guava-Retrying extension which works great.
Retryer<Boolean> retryer = RetryerBuilder.<Boolean>newBuilder()
.retryIfResult(Predicates.<Boolean>isNull())
....
.build();
retryer.call(callable);
I can call easily call it with predicates and it polls until predicate returns false.
Now, maybe I misunderstand predicates but I am trying to create a class that will abstract them.
I wish to call it as follows
MyPoller.poll(new PollCondition<MyClass>() {
#Override public boolean condition() {
return !isValid(result**.getPermissions(), permissionName);
}
});
So I wrote PollCondition class as follows.
public abstract class PollCondition<T> {
public Predicate<T> getCondition() {
return result -> condition();
}
public abstract boolean condition();
}
but MyPoller.poll() call fail to compile - result is not declared.
Any idea?
It seems you don't understand predicates indeed. A predicate is a function that takes an input as argument, and returns a boolean value (usually based on the input, of course).
Let's examine your PollCondition class:
public abstract class PollCondition<T> {
public Predicate<T> getCondition() {
return result -> condition();
}
public abstract boolean condition();
}
So it defines an abstract condition() method that doesn't take anything as argument, and returns a boolean. And it can be "transformed" into a Predicate using getCondition(). This method returns a predicate which takes an input as argument (result), ignores it completely, and always returns the boolean returned by condition().
You then create a PollCondition using
new PollCondition<MyClass>() {
#Override public boolean condition() {
return !isValid(result.getPermissions(), permissionName);
}
}
That would be correct if, in the scope where you execute that code, there was a variable named result. But there is not. resultis in fact an input to your condition. So the class should in fact defined like this:
public abstract class PollCondition<T> {
public Predicate<T> getCondition() {
return result -> condition(result);
}
public abstract boolean condition(T result);
}
And you would then be able to instantiate one using
new PollCondition<MyClass>() {
#Override public boolean condition(MyClass result) {
return !isValid(result.getPermissions(), permissionName);
}
}
But I really, really don't see what that brings over using a simple Predicate directly.
Define MyPoller.poll() like this:
public poll(Predicate<T> predicate);
and use it like this:
MyPoller.poll(result -> !isValid(result.getPermissions(), permissionName));

How do I make my Entity Framework based Repository Class LINQ friendly?

How can I use LINQ if I have wrapped my Entity Framework data context with a Repository class?
I want to do something like:
class A
{
public IRepositiry<T> GetRepository<T>()
{
DbContextAdapter adapter = new DbContextAdapter(ctx);
return new Repository<T>(adapter);
}
}
class B
{
void DoSomething()
{
A a = new A();
IRepository<House> rep = a.GetRepository<House>();
// Do some linq queries here, don't know how.
rep.[get Linqu] (from ...);
}
}
To keep your repository LINQ friendly you need to have some methods or properties on it that return IQueryable<T> or IEnumerable<T>
So in class Repository<T> you would have a method like this:
public class Repository<T>
{
DbContextAdapter ctx;
// other methods omitted
IEnumerable<Houses> GetHouses()
{
return ctx.Houses
}
}
Then in DoSomething you could do this:
void DoSomething()
{
A a = new A();
IRepository<House> rep = a.GetRepository<House>();
var q = from house in rep.GetHouses()
where house.Color = "Purple"
select house;
foreach(var h in q)
{
house.SetOnFire();
}
}
The standard query operators allow queries to be applied to any
IEnumerable-based information source. - MSDN
As long as you write methods that return IEnumerable Collections you will be compatible with LINQ.
at the risk of been completely lazy, what you want to implement is known as the repository pattern, check out Huyrya as its a good article.
Also it's possible to extend the entity classes, so they return instances or lists of themselves (singleton pattern). Aka:
public partial class FOO : FOO
{
public IEnumerable<Foo> GetFooList()
{
using (var context = new FooEntities())
{
return // YOU CODE TO GET LIST OF FOO
}
}
}
Or something like that (code syntax is not right but should give you the general idea). If your entity classes are going to implement similar methods, abstract them into interface contract and get your partial entity classes to implement that interface.

Resources