How to set expectation to params passed to void methods using EasyMock - easymock

I am using EasyMock and EasyMock CE 3.0 to mock dependent layers and test my classes. Below is the scenario for which I am not able to find any solution
I have class to be tested, which calls a dependent class void method that takes an input param, and alters the same param. The method that I am testing is doing some operations based on the altered param, which I have to test now for various scenarios
Consider the below sample, where I have tried to put the same scenario
public boolean voidCalling(){
boolean status = false;
SampleMainBean mainBean = new SampleMainBean();
dependentMain.voidCalled(mainBean);
if(mainBean.getName() != null){
status = true;
}else{
status = false;
}
return status;
}
And the dependentMain class the below method
public void voidCalled(SampleMainBean mainBean){
mainBean.setName("Sathiesh");
}
To have full coverage, I need to have 2 test cases to test both the scenarios where true and false are returned, but I always get false as I am not able to set the behaviour of the void method to alter this input bean. How can I get a true as result in this scenario using EasyMock
Thanks in advance for any help.

Starting from the answer in this answer: EasyMock: Void Methods, you can use IAnswer.
// create the mock object
DependentMain dependentMain = EasyMock.createMock(DependentMain.class);
// register the expected method
dependentMain.voidCalled(mainBean);
// register the expectation settings: this will set the name
// on the SampleMainBean instance passed to voidCalled
EasyMock.expectLastCall().andAnswer(new IAnswer<Object>() {
#Override
public Object answer() throws Throwable {
((SampleMainBean) EasyMock.getCurrentArguments()[0])
.setName("Sathiesh");
return null; // required to be null for a void method
}
});
// rest of test here

Thanks for your reply.. I got the problem resolved... :)
Thanks for the sample code too.
Using the above code snippet, One change that I had to do is,
// register the expected method
dependentMain.voidCalled((SampleMainBean) EasyMock.anyObject());
With this am able to get the updated bean in the method to be tested.
Thanks again for your help.

Related

Easymock: Issue Mocking void DAO method - Unexpected method call

Found a workaround. See solution at the bottom
Ok I have been in EasyMock jail all day and I need some help getting out.
I have a void save() method I am mocking out.
public void save(PurchaseOrder po);
PurchaseOrder is an abstract class that has two children
USPurchaseOrder
CAPurchaseOrder
Here's my code in the JUnit test
MyDAO myDAO = createMock(MyDAO.class);
PurchaseOrder usPurchaseOrder = new USPurchaseOrder(msgUS);
myDAO.save(usPurchaseOrder);
expectLastCall().atLeastOnce();
PurchaseOrder caPurchaseOrder = new CAPurchaseOrder(msgCA);
myDAO.save(caPurchaseOrder);
expectLastCall().atLeastOnce();
replay(myDAO);
//execute code that uses DAO
I get the following error: Unexpected method call MyDAO.save(USPurchaseOrder#1a70b8):
The only problem here is that the DAO signature does not require a USPurchaseOrder, only a PurchaseOrder, which is what I am passing in.
Even doing this produces the same error
myDAO.save(new USPurchaseOrder(msgUS));
What am I doing wrong?
Workaround
Ok, I kept plugging away at this and while I don't understand why I am getting the error, I added the anyObject() to the code to get it to work.
MyDAO myDAO = createMock(MyDAO.class);
myDAO.save(anyObject(OrderRequest.class));
myDAO.save(anyObject(OrderRequest.class));
replay(myDAO);
//execute code that uses DAO
For matching method calls EasyMock uses equals() for method parameters. You should take it into account. So my guess is that you have not implemented equals() in your USPurchaseOrder and the default Object.equals() behavior is used, that compares whether the instances of USPurchaseOrder are the same, which are apparently not.

Rhino mocks unit test method args

I am new to rhino mocks and unit testing in general. I am starting to write some tests for my wpf mvvm app. Here is a sample scenario I am trying to test:
The view model:
List<DataItems> _theData = new List<DataItems>();
public MyViewModel(IServer server)
{
_server = server;
InitializeData();
}
private void InitializeData()
{
_server.GetData(MyCallback);
}
private void MyCallback()
{
_theData = _server.TheData;
}
public List<DataItems> VMData
{
get
{
return _theData;
}
}
Server:
public List<DataItems> TheData
{
get
{
return _cachedData;
}
}
public void GetData(Action callBack)
{
//Populate cached data
...
if(callBack != null)
{
callBack();
}
}
In my test, I want to verify that viewModel.VMData.Count == server.TheData.Count. I tried using rhino mocks to stub the server, pre-poulating TheData with some values. The I called the view model constructor, and then tried to compare the counts.
My problem is that I do not know how to get my server to actually call back into my view model. After the vm constructor is called, InitializeData() is called as expected but the stub server's GetData call is not made.
How can I make this simple test work?
if you are stubbing IServer and expecting that the calling a method on the stub will invoke the implementation in your concrete class, that is your misconception. the GetData method on the stub instance will only return what you tell it to, and not execute any code in the concrete dependency. remember that the only thing your stub IServer object has in common with your concrete implemetation of IServer is that they both implement IServer. expecting that the side effects in the method in your concrete implemenation will happen when calling the method on the stub is just faulty.
as to how to make it work: there's not really a good way to do this test as you are stating with the design of these classes as is. you are trying to test that a side effect occurred in the dependency that you are stubbing out of participation. to really test what you want here and if you want to keep these classes with this relationship, i'd suggest that you don't mock server at all and use the real object. redesign the server so that it depends on another component that loads from the cache so you can stub that thing instead.

Mocking Asynchronous Calls in Silverlight WCF Proxy using Moq

I have a typical Silverlight application with a WCF service and I am using slsvcutil.exe to generate the standard client proxy to communicate with the web service. I am trying to write unit tests and I'm attempting to use the Silverlight Unit Testing framework and Moq to mock the proxy and remove the service dependency for testing.
I am very new to Moq and having a lot of trouble automatically raising the various Completed events on the mocked proxy automatically when service calls are made to simulate the async calls.
In order to make the proxy "mockable" I've created my own simple interface for the generated proxy calls and their completed events:
public interface IServiceProxy
{
void TestAsync(TestRequest request);
void TestAsync(TestRequest request, object userState);
event EventHandler<TestCompletedEventArgs> TestCompleted;
}
I also subclassed the generated proxy object to implement that interface:
public class MyServiceProxy : GeneratedServiceClient, IServiceProxy, ICommunicationObject
{
// ... overloaded proxy constructors
}
After looking at the Moq documentation, this is how I am attempting to set up the mock to expect the TestAsync() call and immediately raise the TestCompleted event with the result in the EventArgs:
[TestMethod]
public void Test_Returns_Expected()
{
var mockProxy = new Mock<IServiceProxy>();
var result = new TestResponse() { Value = true };
this.mockProxy.Setup(
p => p.TestAsync(It.IsAny<TestRequest>()))
.Raises(p => p.TestCompleted += null, new TestCompletedEventArgs(new object[] { result }, null, false, null));
// rest of the test to actually use the mock and assert things
}
Everything builds fine, but when I attempt to run any kind of test using the mock and set break points the TestCompleted event is never being raised when I call TestAsync().
Is there anything obvious that I am missing or any better ideas about mocking these types of async service proxies in Silverlight?
Thanks!
EDIT:
To be more clear what I am actually trying to test is a helper class I made which takes an instance of IServiceProxy and provides a cleaner service interface for my ViewModel to use by accepting Action<TResponse, Exception> callback parameters rather than dealing with callback events in my ViewModel. I understand how I could mock this as well to directly test my ViewModel but I figured it would be nice to test the helper class by itself first.
Here is an example of what I am talking about:
public class HelperClient : IServiceHelper
{
private IServiceProxy proxy;
public HelperClient(IServiceProxy proxy)
{
this.proxy = proxy;
// register to handle all async callback events
this.proxy.TestCompleted += new EventHandler<TestCompletedEventArgs>(TestCompleted);
}
public void Test(TestRequest request, Action<TestResponse, Exception> response)
{
this.proxy.TestAsync(request, response);
}
private void TestCompleted(object sender, TestCompletedEventArgs e)
{
var response = e.UserState as Action<TestResponse, Exception>;
if (response != null)
{
var ex = GetServiceException(e);
if (ex == null)
{
response(e.Result, null);
}
else
{
response(null, ex);
}
}
}
}
So in my test what I am really doing is mocking ISerivceProxy and passing it in and just attempting to test a service call to make sure the wrapper it invoking the Action correctly:
[TestMethod]
[Asynchronous]
public void Test_Returns_Expected()
{
var mockProxy = new Mock<IServiceProxy>();
var helper = new HelperClient(mockProxy.Object);
bool expectedResult = true;
var result = new TestResponse() { Value = expectedResult };
this.mockProxy.Setup(
p => p.TestAsync(It.IsAny<TestRequest>()))
.Raises(p => p.TestCompleted += null, new TestCompletedEventArgs(new object[] { result }, null, false, null));
helper.Test(new TestRequest(), (response, ex) =>
{
Assert.AreEqual(expectedResult, response.Value);
EnqueueTestComplete();
});
}
The problem is that the mocked proxy object is never raising the TestCompleted event so my response action is never getting invoked to finish the test (even though the test appears to complete successfully the Assert is never actually run). Sorry for such a long post, just trying to show you as much code as possible.
EDIT 2
Added [Asynchronous] and call to EnqueueTestComplete() which I realized I may need to make the test wait for the event to be raised. This did not really help, the event is still never raised so the test just hangs and never completes.
EDIT 3
Aliostad's answer was correct that my setup expectation's signature did not match the actual Test() signature allowing me to pass in a response Action as the second param. Stupid mistake, but that is what was preventing Moq from raising the Completed event. I was also forgetting to pass the Action in as the userState object in the TestCompletedEventArgs so that it would actually be invoked when the Completed event was raised. Also, the [Asynchronous] and EnqueueTestCompleted did not seem to be necessary in this case.
Here is updated test code for anyone interested:
[TestMethod]
public void Test_Returns_Expected()
{
var mockProxy = new Mock<IServiceProxy>();
var helper = new HelperClient(mockProxy.Object);
bool expectedResult = true;
var result = new TestResponse() { Value = expectedResult };
Action<TestResponse, Exception> responseAction = (response, ex) =>
{
Assert.AreEqual(expectedResult, response.Value);
};
this.mockProxy.Setup(
p => p.TestAsync(It.IsAny<TestRequest>(), It.IsAny<Action<TestResponse, Exception>>()))
.Raises(p => p.TestCompleted += null, new TestCompletedEventArgs(new object[] { result }, null, false, responseAction));
helper.Test(new TestRequest(), responseAction);
}
Mocking events is quite a pain and unit tests become brittle. But as you said there is no way around it. But normally you would make the call you are trying to test and block the current thread (using Sleep or other methods) until event is raised (or a time-out).
It is actually not clear what you are testing. I can see a mock and a response, where is the actual real object?
I will update my answer accordingly.
UPDATE
I can see a problem here:
helper.Test(new TestRequest(), (response, ex) =>
{
Assert.AreEqual(expectedResult, response.Value);
EnqueueTestComplete();
});
in the last statement, you are putting EnqueueTestComplete(); and you assert but this action will never be used because it is passed to the moq object.
Also you are setting the expectation for TestAsync(It.IsAny<TestRequest>())) (one argument) while you are calling it with two arguments in the HelperClient (this.proxy.TestAsync(request, response);) and that is why it never gets fired since expectation is not met.
just searched for mock asynchronous WCF client and found this question.
to prevent this situation Moq can .Verify() that p.TestAsync() has been invoked.
//will throw MockException if p.TestAsync() has never been called.
this.mockProxy.Verify(p => p.TestAsync(It.IsAny<TestRequest>()), Times.Once());

Silverlight Async Design Pattern Issue

I'm in the middle of a Silverlight application and I have a function which needs to call a webservice and using the result complete the rest of the function.
My issue is that I would have normally done a synchronous web service call got the result and using that carried on with the function. As Silverlight doesn't support synchronous web service calls without additional custom classes to mimic it, I figure it would be best to go with the flow of async rather than fight it. So my question relates around whats the best design pattern for working with async calls in program flow.
In the following example I want to use the myFunction TypeId parameter depending on the return value of the web service call. But I don't want to call the web service until this function is called. How can I alter my code design to allow for the async call?
string _myPath;
bool myFunction(Guid TypeId)
{
WS_WebService1.WS_WebService1SoapClient proxy = new WS_WebService1.WS_WebService1SoapClient();
proxy.GetPathByTypeIdCompleted += new System.EventHandler<WS_WebService1.GetPathByTypeIdCompleted>(proxy_GetPathByTypeIdCompleted);
proxy.GetPathByTypeIdAsync(TypeId);
// Get return value
if (myPath == "\\Server1")
{
//Use the TypeId parameter in here
}
}
void proxy_GetPathByTypeIdCompleted(object sender, WS_WebService1.GetPathByTypeIdCompletedEventArgs e)
{
string server = e.Result.Server;
myPath = '\\' + server;
}
Thanks in advance,
Mike
The best would be to use Reactive Extensions. Then (assuming you'd create an extension method IObservable<string> GetPathByTypeId(string typeId) on WS_WebService1SoapClient you can do this:
proxy
.GetPathByTypeId(TypeId)
.Subscribe(server =>
{
//Here you can do stuff with the returned value
});
As close to having synchronous call as it gets :)
Given the asynch nature of Silverlight you cannot return values from myFunction. Instead you can pass an Action which is executed once the service call is complete. See the example code below. I am not sure if it is considered best practice, but I use this "pattern" a lot and it has always worked fine for me.
EDIT
Updated the code below to include multiple arguments in the callback action.
void DoSomething(Guid TypeId, Action<int, bool> Callback)
{
WS_WebService1.WS_WebService1SoapClient proxy = new WS_WebService1.WS_WebService1SoapClient();
proxy.GetPathByTypeIdCompleted += (s, e) =>
{
string server = e.Result.Server;
myPath = '\\' + server;
//
if (myPath == "\\Server1")
{
Callback(888, true);
}
else
{
Callback(999, false);
}
};
proxy.GetPathByTypeIdAsync(TypeId);
}
void CallDoSomething()
{
DoSomething(Guid.NewGuid(), (returnValue1, returnValue2) =>
{
//Here you can do stuff with the returned value(s)
});
}
Put the processing of the GetPathByTypeId result into the GetPathByTypeIdCompleted callback. Assign mypath there. Make mypath a property and implement the INotifyPropertyChanged interface to notify dependents of Mypath that Mypath has changed.
Observer depends on mypath
Observer sets a notification event for mypath
Get Mypath by asynchronous invocation of GetPathByTypeId
Mypath is set, invokes notifiaction of Observer
Observer works with Mypath

Android Unit Tests Requiring Context

I am writing my first Android database backend and I'm struggling to unit test the creation of my database.
Currently the problem I am encountering is obtaining a valid Context object to pass to my implementation of SQLiteOpenHelper. Is there a way to get a Context object in a class extending TestCase? The solution I have thought of is to instantiate an Activity in the setup method of my TestCase and then assigning the Context of that Activity to a field variable which my test methods can access...but it seems like there should be an easier way.
You can use InstrumentationRegistry methods to get a Context:
InstrumentationRegistry.getTargetContext() - provides the application Context of the target application.
InstrumentationRegistry.getContext() - provides the Context of this Instrumentation’s package.
For AndroidX use InstrumentationRegistry.getInstrumentation().getTargetContext() or InstrumentationRegistry.getInstrumentation().getContext().
New API for AndroidX:
ApplicationProvider.getApplicationContext()
You might try switching to AndroidTestCase. From looking at the docs, it seems like it should be able to provide you with a valid Context to pass to SQLiteOpenHelper.
Edit:
Keep in mind that you probably have to have your tests setup in an "Android Test Project" in Eclipse, since the tests will try to execute on the emulator (or real device).
Your test is not a Unit test!!!
When you need
Context
Read or Write on storage
Access Network
Or change any config to test your function
You are not writing a unit test.
You need to write your test in androidTest package
Using the AndroidTestCase:getContext() method only gives a stub Context in my experience. For my tests, I'm using an empty activity in my main app and getting the Context via that. Am also extending the test suite class with the ActivityInstrumentationTestCase2 class. Seems to work for me.
public class DatabaseTest extends ActivityInstrumentationTestCase2<EmptyActivity>
EmptyActivity activity;
Context mContext = null;
...
#Before
public void setUp() {
activity = getActivity();
mContext = activity;
}
... //tests to follow
}
What does everyone else do?
You can derive from MockContext and return for example a MockResources on getResources(), a valid ContentResolver on getContentResolver(), etc. That allows, with some pain, some unit tests.
The alternative is to run for example Robolectric which simulates a whole Android OS. Those would be for system tests: It's a lot slower to run.
You should use ApplicationTestCase or ServiceTestCase.
Extending AndroidTestCase and calling AndroidTestCase:getContext() has worked fine for me to get Context for and use it with an SQLiteDatabase.
The only niggle is that the database it creates and/or uses will be the same as the one used by the production application so you will probably want to use a different filename for both
eg.
public static final String NOTES_DB = "notestore.db";
public static final String DEBUG_NOTES_DB = "DEBUG_notestore.db";
First Create Test Class under (androidTest).
Now use following code:
public class YourDBTest extends InstrumentationTestCase {
private DBContracts.DatabaseHelper db;
private RenamingDelegatingContext context;
#Override
public void setUp() throws Exception {
super.setUp();
context = new RenamingDelegatingContext(getInstrumentation().getTargetContext(), "test_");
db = new DBContracts.DatabaseHelper(context);
}
#Override
public void tearDown() throws Exception {
db.close();
super.tearDown();
}
#Test
public void test1() throws Exception {
// here is your context
context = context;
}}
Initialize context like this in your Test File
private val context = mock(Context::class.java)

Resources