gemfire cacheclosedexception the cache has not yet been created - unit-testing

I am trying to write unit test for a method which uses an instance of cache as below
public void method(String abc) {
....
....
Cache cache = CacheFactory.getAnyInstance();
....
....
}
I know mocking is the way to resolve this dependency on cache. I am new to mocking and using mockito and not sure on how to pass the mocked cache to the method.
#Mock
Cache cache;
#Test
public void testMethod(){
doReturn(cache).when(CacheFactory.getAnyInstance());
method("abc");
}
The above is what I've tried and got the error.

If you are testing some code path in your application component that calls CacheFactory.getAnyInstance() (such as method("abc")?), then you must ensure that the method gets a reference to the mock Cache another way since you cannot mock a static method on a class (i.e. getAnyInstance() on CacheFactory), at least not without some help from a framework like PowerMock. For example...
public class ExampleApplicationComponent {
public void methodUnderTest(String value) {
...
Cache hopefullyAMockCacheWhenTesting = CachFactory.getAnyInstance();
...
// do something with the Cache...
}
}
Of course, this will fail. So you need to restructure your code a bit...
public class ExampleApplicationComponent {
public void methodUnderTest(String value) {
...
Cache cache = fetchCache();
...
// do something with the (mock) Cache...
}
Cache fetchCache() {
return CacheFactory.getAnyInstance();
}
}
Then in you test case in your test class...
public class ExampleApplicationComponentTest {
#Mock
private Cache mockCache;
#Test
public void methodUsesCacheProperly() {
ExampleApplicationComponent applicationComponent =
new ExampleApplicationComponent() {
Cache fetchCache() {
return mockCache;
}
};
applicationComponent.method("abc");
// assert appropriate interactions were performed on mockCache
}
}
So as you can see, you can override the fetchCache() method in your anonymous ExampleApplicationComponent subclass within you test case to return the mock Cache. Also note, the fetchCache() method was deliberately made "package-private" to limit it's accessibility to primarily the test class (since test classes usually and should reside in the same package as the class under test). This prevents the fetchCache method from escaping and becoming part of your API. While other classes in the same package can access the method of an instance of the ExampleApplicationComponent class, you at least retrain control over that usage (and of course there is not substitute for good documentation).
To see other examples of this in practice, have a look as Spring Data GemFire's CacheFactoryBeanTest class (for instance, and specifically), which does exactly what I described above using Mockito.
Hope this helps.
Cheers!
-John

I was ble to do this with the help of PowerMockito below is the code
mockStatic(CacheFactory.class);
when(CacheFactory.getAnyInstance()).thenReturn(cache);
method("abc");
verifyStatic();
CacheFactory.getAnyInstance();

Related

How to mock this callback using Mockito?

I have this production code in my Presenter:
#UiThread
public void tryToReplaceLogo(String emailInitiallySearchedFor, String logoUrl) {
if(isTheEmailWeAskedApiForStillTheSameAsInTheInputField(emailInitiallySearchedFor)){
if (!TextUtils.isEmpty(logoUrl)) {
downloadAndShowImage(logoUrl);
} else {
view.displayDefaultLogo();
}
}
}
public void downloadAndShowImage(String url) {
final Target target = new Target() {
#Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
view.displayLogoFromBitmap(bitmap);
}
#Override
public void onBitmapFailed(Drawable errorDrawable) {
}
#Override
public void onPrepareLoad(Drawable placeHolderDrawable) {
}
};
Picasso.with(view.getViewContext()).load(url).resize(150, 150).centerInside().into(target);
}
And this unit test for it:
#Test
public void testDisplayLogoIfValidUrlReturnedAndEmailEnteredIsTheSame() throws Exception {
when(loginView.getUserName()).thenReturn(VALID_EMAIL);
when(loginView.getViewContext()).thenReturn(context);
loginLogoFetcherPresenter.onValidateEmailEvent(createSuccessfulValidateEmailEvent(VALID_EMAIL));
waitForAsyncTaskToKickIn();
verify(loginView).displayLogoFromBitmap((Bitmap) anyObject());
}
However, the displayLogoFromBitmap method is never called so my test fails. I need to mock the Target dependency to invoke the onBitmapLoaded method but I don't know how.
Possibly I need to create a static inner class that implements Target so that I can set a Mocked implementation of that in my tests, but how do I invoke the onBitmapLoaded method on the mock?
EDIT:
I have a setter field for Picasso in my LoginPresenter now. In production, (as I am using AndroidAnnotations), I instantiate it in
#AfterInject
void initPicasso() {
picasso = Picasso.with(context):
}
In my test, I mock Picasso like so:
#Mock
Picasso picasso;
#Before
public void setUp() {
picasso = mock(Picasso.class, RETURNS_DEEP_STUBS);
}
(I don't remember why, but I can't use Mockito 2 at this point. It was some incompatibility with something, I think)
In my test case, I got to this point and I don't know what to do:
#Test
public void displayLogoIfValidUrlReturnedAndEmailEnteredIsTheSame() throws Exception {
when(loginView.getUserName()).thenReturn(VALID_EMAIL);
when(loginView.getViewContext()).thenReturn(context);
when(picasso.load(anyString()).resize(anyInt(), anyInt()).centerInside().into(???)) // What do I do here?
loginLogoFetcherPresenter.onValidateEmailEvent(createSuccessfulValidateEmailEvent(VALID_EMAIL));
waitForAsyncTaskToKickIn();
verify(loginView).displayLogoFromBitmap((Bitmap) anyObject());
}
I need to mock the Target dependency
No; do not mock the system under test. Target is as much a part of that system as anything; you wrote the code for it, after all. Remember, once you mock out a class, you commit to not using its implementation, so trying to mock Target to invoke onBitmapLoaded is missing the point.
What's going on here is that you're passing Target—which is real code you wrote that is worth testing—into Picasso, which is external code you didn't write but do depend on. This makes Picasso the dependency worth mocking, with the caveat that mocking interfaces you don't control can get you into trouble if they change (e.g. a method turns final).
So:
Mock your Picasso instance, and the RequestCreator instance Picasso returns when it loads. RequestCreator implements the Builder pattern, so it's a prime candidate for Mockito 2.0's RETURNS_SELF option or other Builder pattern strategies.
Pass the Picasso instance into your system under test, rather than creating it using Picasso.with. At this point you may not need to stub LoginView.getViewContext(), which is a good thing as your test can interact less with hard-to-test Android system classes, and because you've further separated object creation (Picasso) from business logic.
Use an ArgumentCaptor in your test to extract out the Target method that was called on RequestCreator.into.
Test the state of the system before the async callback returns, if you'd like. It's optional, but it's definitely a state your system will be in, and it's easy to forget to test it. You'd probably call verify(view, never()).onBitmapLoaded(any()).
Call target.onBitmapLoaded yourself. You have the target instance at this point, and it should feel correct to explicitly call your code (that is written in your system-under-test) from your test.
Assert your after-callback state, which here would be verify(view).onBitmapLoaded(any()).
Note that there is an existing test helper called MockPicasso, but it seems to require Robolectric, and I haven't reviewed its safety or utility myself.

Mock SomeClass.getClassLoader() when called in method (Mockito / PowerMockito)

I have inherited some code that isn't tested and which loads a resource using a method like :
SomeClass.class.getClassLoader().getResource("somefile");
I've written the following test but there are 0 interactions with the Mock class loader I've created. Can anyone comment on whether this type of test is possible.
public enum SomeClass {
INSTANCE;
public boolean someMethod() {
URL pathToLicense = SomeClass.class.getClassLoader().getResource("somefile");
return false;
}
}
#Test
public void testLicenseWorkflow(){
ClassLoader cl = PowerMockito.mock(ClassLoader.class);
File f = new File("someFile");
assertTrue(f.exists());
logger.info(f.getCanonicalPath() );
when(cl.getResource("somefile")).thenReturn(f.toURL());
verify(cl).getResource("somefile");
assertTrue(SomeClass.INSTANCE.someMethod());
}
Update - Adding a resources via Classloader
I've also tried the following but the someMethod this doens't seem to work either
new URLClassLoader(((URLClassLoader) SomeClass.INSTANCE.getClass().getClassLoader()).getURLs()) {
#Override
public void addURL(URL url) {
super.addURL(url);
logger.info("Calling add URL");
}
}.addURL(f.toURI().toURL());
You are not passing cl to anything. You prepare a mock for a classloader but then proceed to load the resource with another classloader, the one that loaded SomeClass. That is why you have 0 interactions in your mock.
And about your first question, it is possible if somehow you pass your mocked classloader to the method that actually loads the resource. For example, something like
public boolean someMethod(Classloader loader) {
URL pathToLicense = loader.getResource("somefile");
return false;
}
But I have to say that IMO, this test is not very useful, you should be mocking your own components, not java classes. If your goal mocking the classloader is to inject a different file when testing, a better approach is to change your code to receive a Stream and inject a stream connected to the file in production and in testing inject a stream connected to an element in memory.
In other words, resources make for bad testing when they need to be changed at test time

Unit testing - should I use mocks or make private method more visible

I'm looking for some design advice for a new module of the application I am working on, particularly with regards to how to make the design testable.
The problem is very common - load some data from a database, run some operations against the data, and save the result to the database. Most other modules in the application have the following pattern:
private repo; //Set in constructor
public void Run()
{
Stuff stuff = repo.LoadStuff()
Result result = RunOperationsInPrivateMethod(stuff); //private method
repo.SaveResult(result);
}
So to test this, I see that I have a couple of choices:
Inject a mock repo that I can use to return a Stuff and verify a Result.
Refactor RunOperationsInPrivateMethod to protected access, and test
the operations directly.
Am I missing any other options? What are peoples preferences?
In general, don't test private methods, instead, think whether your private method really should be a public method of another class. ie, decompose your object into smaller objects with focused functionality.
eg, perhaps Run should be
private repo; //Set in constructor
private IOperation operation; // injected in constructor or through dependency injection.
public void Run()
{
Stuff stuff = repo.LoadStuff()
Result result = operation.Run(stuff); //private instance with public method
repo.SaveResult(result);
}
then Run would be a public method of an operations class
class SecretOperation : IOperation
{
public void Run(Stuff stuff) { /* secret stuff */ }
}
Then also, you wouldn't have to load a Stuff from a database to test, just create a stuff in a fixture focused on testing SecretOperation. Now your unit tests can be more focused.

Unit Testing, using properties to pass in an interface

Im reading "The art of unit testing" atm and im having some issues with using properties to pass in an interface. The book states the following: "If you want parameters to be optional, use property getters/setters, which is a better way of defining optional parameters than adding different constructors to the class for each dependency."
The code for the property example is as follows:
public class LogAnalyzer
{
private IExtensionManager manager;
public LogAnalyzer ()
{
manager = new FileExtensionManager();
}
public IExtensionManager ExtensionManager
{
get { return manager; }
set { manager = value; }
}
public bool IsValidLogFileName(string fileName)
{
return manager.IsValid(fileName);
}
}
[Test]
Public void
IsValidFileName_NameShorterThan6CharsButSupportedExtension_ReturnsFalse()
{
//set up the stub to use, make sure it returns true
...
//create analyzer and inject stub
LogAnalyzer log = new LogAnalyzer ();
log.ExtensionManager=someFakeManagerCreatedEarlier;
//Assert logic assuming extension is supported
...
}
When/how would i use this feature?? The only scenario i can think of (This is probably wrong!) is if i had two methods in one class,
Method1() retrieves the database connection string from the config file and contains some form of check on the retrieved string.
Method2() then connect to the database and returns some data. The check here could be that that returned data is not null?
In this case, to test Method1() i could declare a stub that implements the IExtensionManager Interface, where the stub has a string which should pass any error checks i have in method1().
For Method2(), i declare a stub which implements the interface, and declare a datatable which contains some data, in the stub class. id then use the properties to assign this to the private manager variable and then call Method2?
The above may be complete BS, so if it is, id appreciate it if someone would let me know and ill remove it.
Thanks
Property injection used to change object's behavior after it was created.
BTW your code is tight coupled to FileExtensionManager, which is concrete implementation of IExtensionManager. How you are going to test LogAnalyzer with default manager? Use constructor injection to provide dependencies to your objects - this will make them testable:
public LogAnalyzer (IExtensionManager manager)
{
this.manager = manager();
}

Should unit tests know about NHibernate?

I'm following on from a previous question. The answer I accepted involves using a generic IRepository to handle basic CRUD, wrapped with a domain specific IMovieRepository which delegates to the generic setup. A further detail involves having a WrapQueryInSession method on the generic IRepository:
IEnumerable<T> WrapQueryInSession(Func<ISession, IEnumerable<T>> query);
I was getting to implementation when I realized that this exposes the NHibernate ISession to consumers of the generic repository. NHibernate is otherwise fully contained in the IRepository implementation, but for that method signature.
This comes to the fore when I want to unit test MovieRepository, by having an IRepository, implemented in RepositoryFake, passed to the MovieRepository constructor:
protected override void BeforeEachTest()
{
_fixture = new MovieRepository(new RepositoryFake());
}
My test class has a private fake repository implementation:
private class RepositoryFake : IRepository<Movie>
{
...
public IEnumerable<Movie> WrapQueryInSession(Func<ISession, IEnumerable<Movie>> query)
{
...
}
...
}
The way this is set up, the test class, and any other consumer of an IRepository implementation, is made aware of the ISession from NHibernate, and thus NHibernate itself. This seems a case of a leaky abstraction.
Is there a better way to fully contain use of NHibernate within an IRepository implementation?
The idea from my answer to your previous question was that the generic IRepository is only known inside your infrastructure layer - it is not published outside of this. When you publish the ISession to the non-generic repositories they gain a very versatile interface, as they have access to the ISession for querying. The problem with not exposing the ISession is that your generic repository will either:
Limit your querying capabilities or
Have a whole host of different methods for querying (basically duplicating the interface of the ISession.
Seems a bit of a waste having NHibernate's querying interface hidden away inside a facade (which the generic Repository would be limited to).
IMO, if you choose nHibernate, you should leverage the power it gives you and live with the dependence through-out your infrastructure dll (including tests). Think of the generic IRepository interface as a helper interface to NHibernate to reduce the amount of duplicate code inside the repositories.
I agree with the principle that NHibernate should not be abstracted completely but I have found that the querying interface of NHibernate can be hidden away without too much hassle and that can happen by using Query objects.
Each query object should leverage the power the NHibernate provides (ISession, ICriteria, IQuery, etc) and can be executed by the implementation of the IRepository.
Having Query objects instead of methods in your repositories offers better testability and it would not require any references to NHibernate in your test classes.
Here is how the whole thing could look like:
public interface IRepository
{
ISession Session { get; }
TResult Query<TResult>(IQuery<TResult> query);
}
public class Repository : IRepository
{
public ISession Session
{
get { return /* Call the session factory to return an ISession */; }
}
public TResult Query<TResult>(IQuery<TResult> query)
{
return query.Execute(Session));
}
}
public interface IQuery<TResult>
{
TResult Execute(QueryContext context);
}
public abstract class Query<TResult> : IQuery<TResult>
{
public abstract TResult Execute(ISession session);
}
public class GetPeopleByName: IQuery<Person>
{
private readonly string _name;
public GetPeopleByName(string name)
{
_name = name;
}
public override IList<Person> Execute(ISeesion session)
{
var query = context.Session.CreateCriteria(typeof(Person))
.Add(Restrictions.Eq("Name", _name));
return query.List<Person>();
}
}
Then you can use the above like:
IRepository repository = /* Get somehow the implementation */
IList<Person> people = repository.Execute(new GetPeopleByName("Anna"));