Invoking Actions from Moq - callback

I've got a service with a method that takes two Actions, one for success and one for failure. Each Action takes a Result parameter that contains additional information...
void AuthoriseUser(AuthDetails loginDetails,
Action<AuthResult> onSuccess,
Action<AuthResult> onFailure);
I'm writing a unit test for a class that is dependant on that service, and I want to test that this class does the correct things in the onSuccess(...) and onFailure(...) callbacks. These are either private or anonymous methods, so how do I setup the mocked service to call either Action?

You can use the Callback method (see also in the Moq quickstart Callbacks section) to configure a callback which gets called with the original arguments of the mocked method call (AuthoriseUser) so you can call your onSuccess and onFailure callbacks there:
var moq = new Mock<IMyService>();
moq.Setup(m => m.AuthoriseUser(It.IsAny<AuthDetails>(),
It.IsAny<Action<AuthResult>>(),
It.IsAny<Action<AuthResult>>()))
.Callback<AuthDetails, Action<AuthResult>, Action<AuthResult>>(
(loginDetails, onSuccess, onFailure) =>
{
onSuccess(new AuthResult()); // fire onSuccess
onFailure(new AuthResult()); // fire onFailure
});

Related

Does MongoCollection.forEach need to be thread safe?

When using the MongoDB Async Java Driver:
Does the following callback need to use a AtomicInteger counter or would a normal int do the job?
Block<Document> theBlock = new Block<Document>() {
AtomicInteger counter = new AtomicInteger();
#Override
public void apply(final Document document) {
counter.incrementAndGet();
}
};
SingleResultCallback<Void> callbackWhenFinished = ...
collection.find().forEach(theBlock, callbackWhenFinished);
The only real difference between the MongoDB Java API and its async counterpart is that the methods of the latter are non-blocking and take callbacks as arguments. This means that what you receive in your callback is equivalent to what the method returns in the non-async API.
Here, you use the find method. It returns a "normal" iterable, so calling forEach on it will not result in multiple threads.
In other words, you don't need an AtomicInteger: your apply method is called sequentially, by the same thread.
If you still have doubts or need a "proof", you can do one of the following:
add a System.out.println(Thread.currentThread().getName()); inside your block. You will see it is always performed by the same thread;
add a breakpoint inside your block, configured to stop only the thread. Once again, the breakpoint will block the whole code.

Calling method from console: "No current object"

I have a method that I need to test. I would like to do so from the console. Here is the method, as well as some metadata from the class:
Include HS.Common
Class Custom.class Extends Ens.BusinessOperation
{
Parameter ADAPTER = "EnsLib.EMail.OutboundAdapter";
Property Adapter As EnsLib.EMail.OutboundAdapter;
Method SendMessage(pSubject As %String, pMessage As %String, pEmailAddresses) As %Status
{
set tSC=$$$OK
set tMailMessage=##class(%Net.MailMessage).%New()
do tMailMessage.To.Insert($PIECE(pEmailAddresses,",",1))
for tI=2:1:$LENGTH(pEmailAddresses,",") {
do tMailMessage.Cc.Insert($PIECE(pEmailAddresses,",",tI))
}
set tMailMessage.Subject=pSubject
set tMailMessage.Charset="iso-8859-1"
set tSC=tMailMessage.TextData.Write(pMessage)
quit:'tSC
Set tSC1=..Adapter.SendMail(tMailMessage)
if 'tSC1 {
//Log warning about being unable to send mail.
do $SYSTEM.Status.DecomposeStatus(tSC1,.err)
$$$LOGWARNING("Could not send email: "_err(err))
kill err
}
quit tSC
}
...other methods here...
}
but when I perform this command:
set tResult = ##class(Custom.class).SendMessage("Test Subject","Test Message","my#email.com")
I get this error:
Set tSC1=..Adapter.SendMail(tMailMessage)
^
<NO CURRENT OBJECT>zSendMessage+11^Custom.class.1
I tried instantiating adapter, much like the property definition, before calling the method but that did not work. How can I call this method from a console session?
this method is an instance method, and you can't call it directly just for some class. Before, you should create an object, and then for that object, you can call any instance methods. But you still trying to call Ensemble classes, it is not so easy, because you should prepare environment, such as configured and started Ensemble Production, your class should be added as an Operation, configured and activated.
set oper=##class(Custom.class).%New("configName")
where configName - name for that operation in your production, by default it is same as class name (e.g. "Custom.class"). And now you can call your method.
write oper.SendMessage("testSubj","test body","my#mail.com")
But I would not recommend such way. It would be better if you test it through production, just sent test messages to this operation.

If you don't block on a future, can it cause a race like condition?

Say I have a controller that has a future call, and then I redirect to another page which expects that call to have computed. Is it possible the future doesn't return fast enough and when I redirect to the other page the data will not be "fresh"?
Example:
class HomeController {
def action1 = Action{
val f1 = Future { ... }
Redirect(routes.HomeController.action2)
}
def action2 = Action {
// expects the call to f1:Future to have executed
}
}
The reason I am asking is should my Service layer return Future's or block? Or should I pass the Future down to the calling code like in my controller.
UserService
save
delete
update
findById
etc. etc..
Should these return Future?
If I expected the call to have computed, I have to block. So is there no hard and fast rule for this?
There's a couple of things in your question that are somewhat tangential, so I'll address them in turn
1) Will the redirect response return before the future returns?
Impossible to tell and, further, it will not behave consistently. For the redirect to not return before the Future has completed its computation, you should use an async action instead, so that the call doesn't respond with the redirect until the Future completes:
def action1 = Action.async { request =>
futureComputation().map { _ => Redirect(routes.HomeController.action2) }
}
2) Should my Service layer return a Future?
The simple answer is yes, if the underlying API is also non-blocking.
The more nuanced answer is yes, even if your service call is blocking, but every other call that is used in your workflow returns a future. This second qualification is about composition and readability.
Suppose the workflow is:
findById
fetchHttpResource (async get)
update (with data from fetch
Because there is one async component, the workflow should be async and you might write it like this:
def workflow(id:UUID):Future[Unit] = {
val user = UserService.findById(id)
fetchHttpResource(id).map { resource =>
val updatedUser = user.copy(x = resource)
UserService.update(updatedUser)
}
}
If UserService returns Future's as well, you could use a for-comprehension instead:
def workflow(id: UUID): Future[Unit] = for {
user <- UserService.findById(id)
resource <- fetchHttpResource(id)
_ <- UserService.update(user.copy(x = resource))
} yield {}
which brings me to
3) Is there a hard and fast rule for using Future's?
Async code is a turtles all the way down affair. Once you have one async call in your chain, your chain has to return a Future and once you have that requirement, composition via for, map, flatMap, etc. and error handling becomes a lot cleaner among Future signatures. The additional benefit is that if you have a blocking call now, maybe in the future you can find an async API to use inside that service, your signature doesn't have to change.
For returning a Future from blocking calls that may fail the best policy is to wrap them with future {}. If however, you have computed data that cannot fail, using Future.successful() is the better choice.
As your code stands your action1 will kick off the code executed in the future then send the redirect to the browser. The is no guarantee that the code in the future will be done before action2 is called.
Howver, assuming this is play framework, you can wait for the code in the future to complete without blocking the current thread, by using the map or onComplete methods on Future to register callbacks, in which you'd complete the request by sending the redirect. You'll need to change your Action to Action.async.

How to stub a super() call with Sinon

I am using Coffeescript and I'm testing using Sinon.js. When testing a method that invokes the method it overwrites, how can I stub the call to super()?
E.g., the method I want to test (a backbone.js model):
class Whatever extends Model
validate: (attributes) ->
validationErrors = super(attributes)
...
validationErrors
In the example, I want to make sure that super() is invoked with the given attributes and that validate returns the validation errors super() returns.
Like this:
it 'calls super and returns its result', ->
whatever = new Whatever()
attributes = sinon.stub()
superValidateStub = sinon.mock(Whatever.__super__)
superValidateStub.expects('validate').withExactArgs(attributes).returns('VALIDATION_RESULT')
expect(whatever.validate(attributes)).to.eql('VALIDATION_RESULT')
superValidateStub.verify()
Hope this helps anyone.

Prototype | keyup Event.stopObserving() not working when handler is bound to class

Here's my beef: I'm observing the document for a keyup and then calling a handler. The handler is calling a function of a class and is bound to the class's context. When the function is called and my conditionals are met, it's supposed to stop observing the handler. But its not.
Created a class, this is the function I'm calling on page:
look_for: function(key_combo) {
this.keys_array = key_combo.split("+");
this.match_key_handler = this.match_keys.bind(this);
document.observe('keyup', this.match_key_handler);
},
This calls the document to observe keyup and calls this.match_keys(). As you can see, it's assigned to a handler because the function needs to be bound. Below is the match_keys functions:
match_keys: function() {
// matching the keys here, blah blah
if(this.keys_matched) {
document.stopObserving('keyup',this.match_key_handler);
}
}
However, when the conditional is met, it doesn't stop observing! If I stopObserving all keyups on the document, it will unregister this function but I want it to only unregister the match_key_handler.
StackOverflow, help me out! Below is another post thats similar. Followed what was on the page but still no dice.
Stop Observing Events with JS Prototype not working with .bind(this)