Mocking a public method that has a private method call inside using Mockito (not Powermockito) - mockito

I am testing for methodA() in the class :
class Test{
public String methodA(String str){
...
methodB("s1","s2");
...
}
private String methodB(String s1, String s2){
...
}
}
What I have tried in my test class:
Method methodBReflect = Test.class.getDeclaredMethod("methodB", Test.class,String.class, String.class);
methodBReflect.setAccessible(true);
Test testForSpy=new Test();
Test spyTest=spy(testForSpy);
doReturn("return string").when(spyTest..)... // <-- What should be done here?
//methodBReflect.invoke(spyTest, "args1","args2");
P.S: I don't need a solution using powermock as I have some organizational constraints using it.

You shouldn't be testing that method A calls method B. You should test that method A does what method A is supposed to do - that is, it gives the correct output for whatever input you give it. Your test shouldn't care whether method A works by calling method B, or by doing all its processing inline.
Therefore, there's no need to mock or stub anything. Your tests will consist of a bunch of calls to method A, along with verification that the output is what you expect.
You only need to use Mockito (or some other mocking framework) when you're testing a class that interacts with another class entirely; not when the class under test interacts with itself.

Related

how do I configure my testng IReporter to accept parameters

IReporter is an interface that has a single void generateReport(List<XmlSuite> xmlSuites, List<ISuite> suites, String outputDirectory) method. I would like to make the behavior of the reporter configurable so I can pass options to it when run on the commandline. The documentation explains how to pass parameters to a reporter on the commandline:
-reporter The extended configuration for a custom report listener. Similar to the -listener option, except that it allows the
configuration of JavaBeans-style properties on the reporter instance.
Example: -reporter
com.test.MyReporter:methodFilter=insert,enableFiltering=true You
can have as many occurences of this option, one for each reporter that
needs to be added.
So it seems I should be able to call testng with -reporter com.my.reporter:key1=value1,key2=value2
but WHERE do I get the values passed in.
I've looked at the XMLReporter provided by testng, and it has a private final XMLReporterConfig config = new XMLReporterConfig(); line, but I can't find out how the config is ever populated.
Magic, that's how it's done :-) It appears it looks for instance variables on your class that implements IReporter with the same name. It does need a stronger type than Object or def though it seems. Here's an example.
class MyReporter implements IReporter {
int foo; //<-- populated when instantiated
#Override
void generateReport(List<XmlSuite> xmlSuites, List<ISuite> suites, String outputDirectory) {
println "foo = ${foo}"
}
}
And then to execute it:
testng ... -reporter 'full.path.to.MyReporter:foo=42'

Mockito testing events

I have a class which generates events e.g.
public class EventSource{
public addEventListener(EventListener listener).....
public raiseEvent(){
Event e=....
listener.handle(e);
}
}
I'm using Mockito to mock an EventListener and want to do an equality on the event object (e.g. event.getTime()..event.getMessage() etc). The event object doesnt have an equals method so I cant easily create another object and do an assert.
Whats the normal way of doing this with Mockito?
It looks like you want to use an argument captor.
For example:
ArgumentCaptor<Event> argument = ArgumentCaptor.forClass(Event.class);
verify(mockedListener).handle(argument.capture());
assertEquals("ExpectedMessage", argument.getValue().getMessage());

AssertWasCalled on method in SystemUnderTest

I'm getting into TDD; using nUnit and RhinoMocks 3.5.
I'm trying to figure out how to AssertWasCalled on a method in the SystemUnderTest (SUT). My understanding is that you can't mock the system under test. In fact, my current test results in an exception because the I'm using the AssertWasCalled on the SUT.
OrdersPresenter:
public void OnViewLoad_GetOrders()
{
var orders = GetOrders();
View.Model.Orders = orders;
}
public List<Orders> GetOrders()
{
return _ordersRepository.GetAll();
}
OrdersPresenterTest:
_ordersPresenter = new OrdersPresenter(_view, _ordersRepository);
[Test]
public void OnViewLoad_GetOrders_Should_Call_GetOrders()
{
_view.Raise(v => v.LoadOrders += _ordersPresenter.OnViewLoad_GetOrders, view, new EventArgs);
_ordersPresenter.AssertWasCalled(d => d.GetOrders); // Getting non-mock exception here
}
How do I Assert GetOrders was called in the SUT? I haven't been able to figure it out in the docs.
Any help is greatly appreciated.
Edit:
I understand the GetOrders method in the SUT should be private. I went back thru Roy Osherove's Art of Unit Testing to see how to test private methods. Roy says making a method public (to test against) is not necessarily a bad thing, so I will keep it public.
So I've written a test for GetOrders and I assert the return value ShouldBe a list of orders. That said, I believe I need to restructure my test for OnViewLoad_GetOrders by stubbing the value I get from GetOrders and asserting the results of my actions on that object.
Can someone confirm and explain?
You can not use AssertWasCalled() on not-mocked objects. Just abstract class OrdersPresenter by an interface (use Extract Interface refactoring technique) and then
var ordersPresenter = MockRepository.GenerateMock<IOrderRepository>();
view.Raise(...);
_ordersPresenter.AssertWasCalled(d => d.GetOrders);
BTW,
for me it is not clear why RhinoMocks not used generic parameter constraint for AssertWasCalled
public static void AssertWasCalled<T>(this T mock, Action<T> action,
Action<IMethodOptions<object>> setupConstraints)
Basically T is not limited, but I believe it would be better limit it to somethign like IMockMarkerInterface

Groovy: stub typed reference

I have a Groovy class similar to
class MyClass {
Foo foo
}
Under certain circumstances I don't want to initialize foo and want to stub out all the calls to it. Any methods that return a value should do nothing. I could do it like this:
Foo.metaClass.method1 = {param -> }
Foo.metaClass.method2 = { -> }
Foo.metaClass.method3 = {param1, param2 -> }
While this will work, it has a couple of problems
Tedious and long-winded, particularly if Foo has a lot of methods
This will stub out calls to any instance of Foo (not just foo)
Although Groovy provides a StubFor class, if I do this:
this.foo = new groovy.mock.interceptor.StubFor(Foo)
I get a ClassCastException at runtime. Although this would work if I could redefine foo as:
def foo
But for reasons I won't go into here, I can't do that.
Thanks,
Don
I found the solution:
this.foo = {Object[] args -> println "I don't do anything"} as Foo
You need to pass the Foo instance to your MyClass object. In the test, pass in a stub implementation. In the real program pass in a real implementation.
You don't need any special framework to write the stub. If you're only stubbing queries to Foo and are not interested in expecting commands to it, then it's easier to write a stub implementation by hand. A mock object library is overkill and will confuse later readers of the code who will expect the test to include expectations.
You could make a stub with a map as well, making it possible to stub multiple methods, like so:
def stubbedList = [empty : { false }, get: {index -> "always return this"}] as ArrayList
If you stub out a class (like in the ArrayList example above), then the methods that you do not override are kept as they are implemented in the class. You can also stub out interfaces obviously.
If you are in need of mocking capabilities (i.e verifying behaviour in a test, like counting the number of calls to a given method), I would strongly recommend checking out the Spock test framework. It has really great support for more advanced stubbing and mocking.
I'm guessing this is for test purposes only.
The line:
Foo foo
creates a getter / setter pair, so you can inject a mock in your test cases by doing this:
new MyClass().foo = new MockFoo()
If you don't want to create the mock for yourself, try a mocking library. I recommend using mockito. With this small library you can do something like this:
import static org.mockito.Mockito.*;
new MyClass().foo = mock(Foo.class);

How can I intercept execution of all the methods in a Java application using Groovy?

Is it possible to intercept all the methods called in a application? I'd like to do something with them, and then let them execute. I tried to override this behaviour in Object.metaClass.invokeMethod, but it doesn't seem to work.
Is this doable?
Have you looked at Groovy AOP? There's very little documentation, but it allows you to define pointcuts and advice in a conceptually similar way as for AspectJ. Have a look at the unit tests for some more examples
The example below will match all calls to all woven types and apply the advice before proceeding:
// aspect MyAspect
class MyAspect {
static aspect = {
//match all calls to all calls to all types in all packages
def pc = pcall("*.*.*")
//apply around advice to the matched calls
around(pc) { ctx ->
println ctx.args[0]
println ctx.args.length
return proceed(ctx.args)
}
}
}
// class T
class T {
def test() {
println "hello"
}
}
// Script starts here
weave MyAspect.class
new T().test()
unweave MyAspect.class
First of all, overriding Object.metaClass.invokeMethod doesn't work because when Groovy tries to resolve a method call for a type X, it checks the metaClass of X, but not the metaClass of its parent class(es). For example, the following code will print "method intValue intercepted"
Integer.metaClass.invokeMethod = {def name, def args ->
System.out.println("method $name intercepted")
}
6.intValue()
// Reset the metaClass
Integer.metaClass = null
But this code will not:
Object.metaClass.invokeMethod = {def name, def args ->
System.out.println("method $name intercepted")
}
6.intValue()
// Reset the metaClass
Object.metaClass = null
Your question was "Is it possible to intercept all the methods called in a application?", but could you be a bit more precise about whether you want to:
Intercept calls to Groovy methods, Java methods, or both
Intercept calls to only your Groovy/Java methods or also intercept calls to Groovy/Java library classes
For example, if you only want to intercept calls to your Groovy classes, you could change your classes to implement GroovyInterceptable. This ensures that invokeMethod() is invoked for every method called on those classes. If the nature of the interception (i.e. the stuff you want to do before/after invoking the called method) is the same for all classes, you could define invokeMethod() in a separate class and use #Mixin to apply it to all your classes.
Alternatively, if you also want to intercept calls to Java classes, you should check out the DelegatingMetaClass.

Resources