Mockito using spy object running actual code hence giving error - jax-rs

I have this bunch of code. First is a test class method testEndPoint(), I have also included the class to be tested EndPointClass.
When I run this testmethod, it tries to run the actual send http Call method instead of mocking or a dummy call, hence it gives a 500 not found error.
I know somewhere the code needs to be corrected not sure where.
Here's the code
public void testEndPoint(){
OutputObject output = new OutputObject();
EndPointClass epClass = new EndPointClass();
EndPointClass epClassSpy = Mockito.spy(epClass);
List<JacksonJsonProvider> providers = new ArrayList<JacksonJsonProvider>();
providers.add(mockCustomJacksonProvider);
WebClient client = WebClient.create("http://example.org/home",providers);
WebClientWrapper webClientWrapper = new WebClientWrapper(client);
WebClientWrapper spyWebClient = Mockito.spy(webClientWrapper);
Mockito.when(spyWebClient.invoke(Mockito.any(String.class),Mockito.any(Object.class),Mockito.eq(OutputObject.class))).thenReturn(output);
Mockito.when(epClassSpy.webCall(spyWebClient)).thenReturn(output);
OutputObject response = epClassSpy.sendRequest("ABC", "ABCToken");
}
public class EndPointClass{
public OutputObject sendRequest(String input, String authToken){
List<JacksonJsonProvider> providers = new ArrayList<JacksonJsonProvider>();
providers.add(downloadsJacksonProvider);
WebClient client = WebClient.create(olsDownloadUrl+path, providers);
if (null == timeOut) {
timeOut = 60000;
}
HTTPConduit http = (HTTPConduit) WebClient.getConfig(client).getConduit();
HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy();
httpClientPolicy.setConnectionTimeout(0);
httpClientPolicy.setReceiveTimeout(timeOut);
http.setClient(httpClientPolicy);
client.type("application/json");
client.accept("application/json");
client.header("x-auth-Token", authToken);
client.query("input", input);
OutputObject output = null;
WebClientWrapper clientWrapper = new WebClientWrapper(client);
output = webCall(clientWrapper);
return output;
}
public OutputObject webCall(WebClientWrapper clientWrapper) {
return clientWrapper.invoke(HttpMethod.GET, null, OutputObject.class);
}
}

From the official documentation
Important gotcha on spying real objects!
Sometimes it's impossible or impractical to use when(Object) for stubbing spies. Therefore when using spies please consider doReturn|Answer|Throw() family of methods for stubbing. Example:
List list = new LinkedList();
List spy = spy(list);
//Impossible: real method is called so spy.get(0) throws ndexOutOfBoundsException (the list is yet empty)
when(spy.get(0)).thenReturn("foo");
//You have to use doReturn() for stubbing
doReturn("foo").when(spy).get(0);
So just change your Mockito.when(...) to Mockito.doReturn(...) that should do the trick.

Related

Genesys Platform : Get Call Details From Sip Server

I want to get Call Details from Genesys Platform SIP Server.
And Genesys Platform has Platform SDK for .NET .
Anybod has a SIMPLE sample code which shows how to get call details using Platform SDK for .NET [ C# ] from SIP Server?
Extra Notes:
Call Details : especially i wanted to get AgentId for a given call
and
From Sip Server : I am not sure if Sip Server is the best candiate to
take call details. So open to other suggestions/ alternatives
You can build a class that monitor DN actions. Also you watch specific DN or all DN depending what you had to done. If its all about the call, this is the best way to this.
Firstly, you must define a TServerProtocol, then you must connect via host,port and client info.
var endpoint = new Endpoint(host, port, config);
//Endpoint backupEndpoint = new Endpoint("", 0, config);
protocol = new TServerProtocol(endpoint)
{
ClientName = clientName
};
//Sync. way;
protocol.Open();
//Async way;
protocol.BeginOpen();
I always use async way to do this. I got my reason thou :) You can detect when connection open with event that provided by SDK.
protocol.Opened += new EventHandler(OnProtocolOpened);
protocol.Closed += new EventHandler(OnProtocolClosed);
protocol.Received += new EventHandler(OnMessageReceived);
protocol.Error += new EventHandler(OnProtocolError);
Here there is OnMessageReceived event. This event where the magic happens. You can track all of your call events and DN actions. If you go genesys support site. You'll gonna find a SDK reference manual. On that manual quiet easy to understand there lot of information about references and usage.
So in your case, you want agentid for a call. So you need EventEstablished to do this. You can use this in your recieve event;
var message = ((MessageEventArgs)e).Message;
// your event-handling code goes here
switch (message.Id)
{
case EventEstablished.MessageId:
var eventEstablished = message as EventEstablished;
var AgentID = eventEstablished.AgentID;
break;
}
You can lot of this with this usage. Like dialing, holding on a call inbound or outbound even you can detect internal calls and reporting that genesys platform don't.
I hope this is clear enough.
If you have access to routing strategy and you can edit it. You can add some code to strategy to send the details you need to some web server (for example) or to DB. We do such kind of stuff in our strategy. After successful routing block as a post routing strategy sends values of RTargetPlaceSelected and RTargetAgentSelected.
Try this:
>
Genesyslab.Platform.Contacts.Protocols.ContactServer.Requests.JirayuGetInteractionContent
JirayuGetInteractionContent =
Genesyslab.Platform.Contacts.Protocols.ContactServer.Requests.JirayuGetInteractionContent.Create();
JirayuGetInteractionContent.InteractionId = "004N4aEB63TK000P";
Genesyslab.Platform.Commons.Protocols.IMessage respondingEventY =
contactserverProtocol.Request(JirayuGetInteractionContent);
Genesyslab.Platform.Commons.Collections.KeyValueCollection keyValueCollection =
((Genesyslab.Platform.Contacts.Protocols.ContactServer.Events.EventGetInteractionContent)respondingEventY).InteractionAttributes.AllAttributes;
We are getting AgentID and Place as follows,
Step-1:
Create a Custome Command Class and Add Chain of command In ExtensionSampleModule class as follows,
class LogOnCommand : IElementOfCommand
{
readonly IObjectContainer container;
ILogger log;
ICommandManager commandManager;
public bool Execute(IDictionary<string, object> parameters, IProgressUpdater progress)
{
if (Application.Current.Dispatcher != null && !Application.Current.Dispatcher.CheckAccess())
{
object result = Application.Current.Dispatcher.Invoke(DispatcherPriority.Send, new ExecuteDelegate(Execute), parameters, progress);
return (bool)result;
}
else
{
// Get the parameter
IAgent agent = parameters["EnterpriseAgent"] as IAgent;
IIdentity workMode = parameters["WorkMode"] as IIdentity;
IAgent agentManager = container.Resolve<IAgent>();
Genesyslab.Desktop.Modules.Core.Model.Agents.IPlace place = agentManager.Place;
if (place != null)
{
string Place = place.PlaceName;
}
else
log.Debug("Place object is null");
CfgPerson person = agentManager.ConfPerson;
if (person != null)
{
string AgentID = person.UserName;
log.DebugFormat("Place: {0} ", AgentID);
}
else
log.Debug("AgentID object is null");
}
}
}
// In ExtensionSampleModule
readonly ICommandManager commandManager;
commandManager.InsertCommandToChainOfCommandAfter("MediaVoiceLogOn", "LogOn", new
List<CommandActivator>() { new CommandActivator()
{ CommandType = typeof(LogOnCommand), Name = "OnEventLogOn" } });
enter code here
IInteractionVoice interaction = (IInteractionVoice)e.Value;
switch (interaction.EntrepriseLastInteractionEvent.Id)
{
case EventEstablished.MessageId:
var eventEstablished = interaction.EntrepriseLastInteractionEvent as EventEstablished;
var genesysCallUuid = eventEstablished.CallUuid;
var genesysAgentid = eventEstablished.AgentID;
.
.
.
.
break;
}

Marketo rest Api create lead

I have a question about this create/Update leads API, http://developers.marketo.com/documentation/rest/createupdate-leads/.
There is no sample code for C# or JAVA. Only ruby available. So I have to try it by myself. But I always get null return from the response.
Here is my code:
private async Task<CreateLeadResponseResult> CreateLead(string token)
{
string url = String.Format(marketoInstanceAddress+"/rest/v1/leads.json?access_token={0}", token);
var fullUri = new Uri(url, UriKind.Absolute);
CreateLeadResponseResult createLeadResponse = new CreateLeadResponseResult();
CreateLeadInput input = new CreateLeadInput { email = "123#123.com", lastName = "Lee", firstName = "testtesttest", postCode = "00000" };
CreateLeadInput input2 = new CreateLeadInput { email = "321#gagaga.com", lastName = "Lio", firstName = "ttttttt", postCode = "00000" };
List<CreateLeadInput> inputList = new List<CreateLeadInput>();
inputList.Add(input);
inputList.Add(input2);
CreateLeadRequest createLeadRequest = new CreateLeadRequest() { input = inputList };
JavaScriptSerializer createJsonString = new JavaScriptSerializer();
string inputJsonString = createJsonString.Serialize(createLeadRequest);
using (var client = new HttpClient())
{
HttpResponseMessage response = await client.PostAsJsonAsync(fullUri.OriginalString, inputJsonString).ConfigureAwait(false);
// I can see the JSON string is in the message body in debugging mode.
if (response.IsSuccessStatusCode)
{
createLeadResponse = await response.Content.ReadAsAsync<CreateLeadResponseResult>();
}
else
{
if (response.StatusCode == HttpStatusCode.Forbidden)
throw new AuthenticationException("Invalid username/password combination.");
else
throw new ApplicationException("Not able to get token");
}
}
return createLeadResponse;}
//get null here.
Thank you.
-C.
The best way to debug this is to capture the exact URL, parameters and JSON that are submitted by your app and try submitting those manually via a tool like Postman (Chrome plug-in) or SOAP UI. Then you see the exact error message, which you can look up here: http://developers.marketo.com/documentation/rest/error-codes/. Based on that you can update your code. I don't know much about Java, but this is how I got my Python code to work.
Your example code was really helpful in getting my own implementation off the ground. Thanks!
After playing with it for a bit, I realized that the JavaScriptSerializer step is unnecessary since PostAsJsonAsync automatically serializes whatever object you pass to it. The double serialization prevents Marketo's API from processing the input.
Also, I agree with Jep that Postman is super helpful. But in the case of this error, Postman was working fine (using the contents of inputJsonString) but my C# code still didn't work properly. So I temporarily modified the code to return a dynamic object instead of a CreateLeadResponseResult. In debugging mode this allowed me to see fields that were discarded because they didn't fit the CreateLeadResponseResult type, which led me to the solution above.

RavenDB IsOperationAllowedOnDocument not supported in Embedded Mode

RavenDB throws InvalidOperationException when IsOperationAllowedOnDocument is called using embedded mode.
I can see in the IsOperationAllowedOnDocument implementation a clause checking for calls in embedded mode.
namespace Raven.Client.Authorization
{
public static class AuthorizationClientExtensions
{
public static OperationAllowedResult[] IsOperationAllowedOnDocument(this ISyncAdvancedSessionOperation session, string userId, string operation, params string[] documentIds)
{
var serverClient = session.DatabaseCommands as ServerClient;
if (serverClient == null)
throw new InvalidOperationException("Cannot get whatever operation is allowed on document in embedded mode.");
Is there a workaround for this other than not using embedded mode?
Thanks for your time.
I encountered the same situation while writing some unit tests. The solution James provided worked; however, it resulted in having one code path for the unit test and another path for the production code, which defeated the purpose of the unit test. We were able to create a second document store and connect it to the first document store which allowed us to then access the authorization extension methods successfully. While this solution would probably not be good for production code (because creating Document Stores is expensive) it works nicely for unit tests. Here is a code sample:
using (var documentStore = new EmbeddableDocumentStore
{ RunInMemory = true,
UseEmbeddedHttpServer = true,
Configuration = {Port = EmbeddedModePort} })
{
documentStore.Initialize();
var url = documentStore.Configuration.ServerUrl;
using (var docStoreHttp = new DocumentStore {Url = url})
{
docStoreHttp.Initialize();
using (var session = docStoreHttp.OpenSession())
{
// now you can run code like:
// session.GetAuthorizationFor(),
// session.SetAuthorizationFor(),
// session.Advanced.IsOperationAllowedOnDocument(),
// etc...
}
}
}
There are couple of other items that should be mentioned:
The first document store needs to be run with the UseEmbeddedHttpServer set to true so that the second one can access it.
I created a constant for the Port so it would be used consistently and ensure use of a non reserved port.
I encountered this as well. Looking at the source, there's no way to do that operation as written. Not sure if there's some intrinsic reason why since I could easily replicate the functionality in my app by making a http request directly for the same info:
HttpClient http = new HttpClient();
http.BaseAddress = new Uri("http://localhost:8080");
var url = new StringBuilder("/authorization/IsAllowed/")
.Append(Uri.EscapeUriString(userid))
.Append("?operation=")
.Append(Uri.EscapeUriString(operation)
.Append("&id=").Append(Uri.EscapeUriString(entityid));
http.GetStringAsync(url.ToString()).ContinueWith((response) =>
{
var results = _session.Advanced.DocumentStore.Conventions.CreateSerializer()
.Deserialize<OperationAllowedResult[]>(
new RavenJTokenReader(RavenJToken.Parse(response.Result)));
}).Wait();

BuildCommands argument in Rob Conery's Massive

I am using Rob Conery's Massive.
The method List<DbCommand> BuildCommands(params object[] things), according to the methods comments, is supposed to take objects that "can be POCOs, Anonymous, NameValueCollections, or Expandos". But this:
var x = new { Id = new Guid("0F66CDCF-C219-4510-B81A-674CE126DD8C"), Name = "x", DisplayName = "y" };
myTable.BuildCommands(x);
Results in an InvalidCastException. Which reasonable since in the Massive.cs a cast from the passed in anonymous type to an ExpandoObject is attempted.
Why does the comment state you can pass in anything? Is there some other way to build commands from non-ExpandoObjects?
Here's some more code:
public static void ThisFails()
{
DynamicModel myTable = new DynamicModel("myConnectionString", tableName: "dbo.MyTable", primaryKeyField: "Id");
var updateMe = new { Id = new Guid("DF9A2F1B-3556-4EAC-BF2B-40E6821F3394"), Name = "abcx", DisplayName = "x" };
var commands = myTable.BuildCommands(updateMe); // This fails
myTable.Execute(commands);
}
public static void ThisSucceeds()
{
DynamicModel myTable = new DynamicModel("myConnectionString", tableName: "dbo.MyTable", primaryKeyField: "Id");
dynamic updateMe = new ExpandoObject();
updateMe.Id = new Guid("DF9A2F1B-3556-4EAC-BF2B-40E6821F3394");
updateMe.Name = "abcx";
updateMe.DisplayName = "x";
var commands = myTable.BuildCommands(updateMe);
myTable.Execute(commands);
}
The code that fails results in:
Unable to cast object of type
'<>f__AnonymousType03[System.Guid,System.String,System.String]' to
type <br/>
'System.Collections.Generic.IDictionary2[System.String,System.Object]'.
It's thrown from the first line in your method
public virtual DbCommand CreateUpdateCommand(dynamic expando, object key)
{
var settings = (IDictionary<string, object>)expando;
...
To me it looks like there should be a call to your extension method ToExpando before CreateUpdateCommand is called?
I think this is why people make methods private and public :). You're not supposed to call BuildCommands directly (though the code you have here still should work). I have a feeling there might be a bug that was committed in a patch.
That said - I believe this will work if you call myTable.Update() or myTable.Insert().
This last part answers the question - in terms of a possible "issue" - let's take that to Github.

Rhino Mock 3.6 Repository Expected #0, Actual#1

I'm using Rhino Mock 3.6 Repository and Nhibernate. But I'm getting ExpectationViolationException Expected#0, Actual #1. I've spent two days on it. I don't know what i'm doing wrong. Here is my code. I'm getting error on mockRepository.Save(user) line.
var username = "abcdef";
var mocks = new MockRepository();
var validationResults = new ValidationResults();
IDataQuery query = mocks.StrictMock<IDataQuery>();
UserRepository mockRepository = mocks.StrictMock<UserRepository>(query);
var user = mocks.StrictMock<User>();
user.FirstName = "javed";
user.LastName = "ahmad";
user.UserName = "abc";
user.Password = "password";
user.Email = "nadeem#test.com";
user.IsActive = true;
user.CreatedBy = 1000000;
user.CreatedDate = DateTime.Today;
user.ModifiedBy = 1000000;
user.ModifiedDate = DateTime.Today;
Expect.Call(user.Validate()).Return(validationResults);
mocks.ReplayAll();
mockRepository.Save(user);
Thanks in Advance.
Thanks
Imran
You're using a StrickMock which means the only calls to be considered valid are the calls you set Expectations for. Since you didn't set an Expectation that Save would be called, you're getting an error.
Normally this means RhinoMock expects you to call user.Validate() once, but you call the method twice. You can either check that you call the method only once or change
Expect.Call(user.Validate()).Return(validationResults);
to
Expect.Call(user.Validate()).Return(validationResults).Repeat.Twice();
You appear to be mocking everything even the sut i.e. userrepository
you should be setting up mocks on interfaces that will be used inside the userrepository. you will need to pass these in to the userrepository to override their default behaviour somehow.
You need to decide what you actually want to test.
The code above implies the following to me
class UserRepository
{
public void Save(IUser user)
{
validationResult = user.Validate();
if (validationResult==null)
{
dal.Save(user);
}
}
}
That's just a guess, but the point is the code you currently have should only be mocking the user if your intention is to test that the validate method is called within the userrepository.save method