If I mock an object and/or stub a method in my spec, will that mock be used even though it's only called indirectly? - ruby-on-rails-3

I am new to mocking and stubbing, but I think I have a circumstance where their use would be ideal.
In my application, when a user saves a Product, an after_save callback fires that creates Publication instances which cause the product data to be sent to certain 3rd parties via API.
I have a request spec for Product that tests my CRUD operations.
If I stub either the API methods or mock the Publication model, will those mocks/stubs be used in my spec even though they are actually called in the Product after_save callback? I'm confused about this point.
Update
I figured I would just do it like this:
Publication.any_instance.stub(:publist).and_return(true)
And do that at the beginning of my test. That way whatever instance is created would be handled. Is that how it works?

Yes that stub will do what it says and the publist method on any instance of the publication class will always return true.
Instead of putting it "at the top" though do something like.
context 'when there is a publist' do
Publication.any_instance.stub(:publist).and_return(true)
it 'should ...' do
...
end
end
then if required you can do tests without the stub, or tests where publist returns false in other context blocks and be nice and clear in the spec.

Related

Is it a good practice the attach an event related parameter to an object's model as a variable?

This is about an API handling the validation during saving an object. Which means that the front-end client sends a request to the API to a specific end point, then on the back-end the API creates a new object if the right conditions are meet.
Right now the regular method that we use is that the models has a ruleset for each fields and then the validation is invoked when the save function is invoked, but technically the validation is done right before the object is saved into the database.
Then during today's code review I came across a solution which I wasn't sure if it's a good practice or not. And it was about that the front-end must send a specific parameter to the API every time. This is because other APIs are using our API as well, and we needed to know if the request was sent as and API request or a browser request. If this parameter is present then we want to execute an extra validation function on a specific field.
(1)If I would have to implement it, then I would check the incoming parameter in the service handler or in the controller level, and if I got one, I would invoke the validation right away, and if it fails I would throw an error.
(2)The implementation I saw however adds an extra variable to the model, and sets the model variable when there is an incoming parameter, then validates only when the save function is invoked on the object(which first validates the ruleset defined on the object fields, then saves the object into the database)
So my problem with (2) is that the object now grown bigger with an extra variable that is only related to a specific event. So I would say it's better to implement (1). But (2) also has an advantage, and that is when you create the object on different end point by parsing the parameters, then the validation will work there as well, even if the developer forget to update the code there.
Now this may seems like a silly question because, why would I care about just 1 extra variable, but this is like a bedrock of something good or bad. So if I say this is ok, then from now on the models will start growing with extra variables that are only related to specific events, which I think should be handled on the controller/service handler level. On the other hand the code would be more reliable if it's not the developer who should remember all the 6712537 functionalities and keep them in mind when makes some changes somewhere. Let's say all the devs will get heart attack tomorrow from the excitement of an amazing discovery, and a new developer has to work on the project while he doesn't know about these small details, and then he has to change something on the code that is related to this functionality - so that new feature should be supported by this old one as well.
So my question is if is there any good practice on this, and what do you think what would be the best approach?
So I spent some time on thinking on the solution, and I think the best is to have an array of acceptable trigger variables in the model class. Then when the parameters are passed to the model on the controller level, then the loader function can be modified that it takes the trigger variables from the parameters and save it in the model's associative array variable that stores the trigger variables.
By default this array is empty, and it doesn't matter how much new variables are needed to be created, it will only contain the necessary ones when those are used.
Then of course the loader function needs to be modified in a way that it can filter out the non trigger variables as well as it is done for the regular fields, and there can be even a rule set of validation on the trigger variables if necessary.
So this solves the problem with overgrowing the object with unnecessary variables and the centralized validation part, because now the validation can be always done in the model instead of the controller.
And since the loader function is modified to store the trigger variables in the model's trigger variables array variable, the developer never has to remember that this functionality was created. Which is good, because in the future when he creates a new related function or end point that should handle object creation, he will not miss it to validate it against the old functionality, because the the loader function that he modified in the past like this will handle it for him.
It needs to be noted tho, that since the loader function doesn't differentiate between the parameters, and where to load them other then checking the names of the parameters with the filter functions, these parameter names should be identical from each other, otherwise a buggy functionality can be created accidentally. Like if you forget that a model attribute with the same name was used, then you can accidentally trigger an event that was programmed to be triggered if the trigger variable with the same name is present. However this can be solved by prefixing the trigger variables for example.

Delphi, enhance code of non-virtual methods or events

Although more of a Delphi language question, will use a specific example to try and get the idea across better:
using Delphi's TWebModule for an HTTP server, we can define endpoints as actions, and assign those actions an OnAction event, to execute code when a request is made to this given endpoint.
many, if not most of those actions require authorization: that is, they all start with the same block of code that checks for valid credentials and decides whether to allow the request to execute or not. So I started looking at how one could "group" a set of similar actions into maybe a subclass of the default action class (TWebActionItem) that adds authorization-specific code. One might also want to execute some generic before/after methods.
pseudo-code would look something like this, where TAuthWebActionItem is a subclass of TWebActionItem adding authorization code, and before/after method calls:
function TAuthWebActionItem.OnAction
begin
FBeforeAction // execute some initialization code
if authorized then // auth ok?
inherited // proceed
else
'you are not authorized'
FAfterAction // execute some finalization code
end
we would then create a TAuthWebActionItem, add it to the TWebModule's list of actions, and we're done.
however, the TWebModule and TWebActionItem classes do not offer virtual methods for overriding. Using "reintroduce" instead of "override" would not solve it either, as the TWebModule's actions list items are still of type TWebActionItem: calling the OnAction of a superclass, even if reintroduced, will not execute the subclass' code.
How would one bypass such limitations / constraints in the classes being used, to achieve what's outlined in the pseudo-code above?

Discard message from nServiceBus mutator

I need to discard a message if a specific header is present.
I tried to implement a IMutateTransportMessages and call DoNotContinueDispatchingCurrentMessageToHandlers() method inside MutateIncoming but the message is dispatched to handlers anyway.
I can discard the message using an handler but I don't like it because I need also to specify the handlers' order.
Any solution?
Thanks,
Federico
I don't think this will be possible from a message mutator. After all, this isn't really the kind of activity a message mutator should be doing - it has nothing to do with changing the structure of the message.
I agree with you that it sounds messy to do this in a handler, because you're right - then you are very dependent upon the handler order.
Discarding a message due to the presence (or absence) of a header is an infrastructure concern, and since you are using NServiceBus V5, the best way to customize the infrastructure is by customizing the message handling pipeline.
Here's the relevant documentation that covers creating a behavior and inserting it into the pipeline but here's the short version:
You need to create a behavior that implements IBehavior<IncomingContext>. All of the behaviors together form a behavior chain that progress to the next step by calling next() - an Action present in the implementation) method.
Within the behavior, check for your header. To stop processing the message, just don't call next() and call context.DoNotInvokeAnyMoreHandlers() instead.
Create a class inheriting RegisterStep which, from its constructor, will define where in the pipeline to insert your behavior. You could register it right before the MutateIncomingTransportMessage step.
Create a class implementing INeedInitialization (note that this could be the same as the RegisterStep class) which calls busConfig.Pipeline.Register<TClassThatInheritsRegisterStep>().
Again, that's the short version. Check out the docs for the full story and an example.
Shameless plug: This process is also described in detail in Learning NServiceBus - Second Edition in Chapter 7, with an example.

Method Interception, replace return value

We’re using Ninject.Extensions.Interception (LinFu if it matters) to do a few things and I want to know if its possible to return a value form the method being intercepted.
EG
A Call is made into one of our repository methods
Our Interceptor gets the BeforeInvoke event, we use this to look into the ASP.NET Cache to see if there is any relevant data
- Return the relevant data (this would cause the method to return immediately and NOT execute the body of the method
- Or Allow the method to run as per normal
Extra points if in the AfterInvoke method we take a peek at the data being returned and add it to the cache.
Has anybody done something similar before?
From your question I assume that you derive from SimpleInterceptor. This will not allow to return imediately. Instead you have to implement the Iinterceptor interface. You can decide to call the intercepted method by calling the Proceed method on the invocation or not.

How do you test a referenced class that performs internal operations?

How would I test the following code?
Public Sub SetSerialIdForDevice()
Try
Dim component As Object = container.getComponentRef("componentInterface")
If component IsNot Nothing Then
component.SetupDeviceSerialID(container.serialNumbers)
Else
serialfound = False
End If
Catch ex As Exception
'' error handling
End Try
End Sub
Project references (or components as they're called here) are loaded at runtime into a singleton 'container.' We call the component that interfaces with a device by using the container.getComponentRef("< name of component we're looking for >"). We then invoke a method on this component to set the serial id, which is stored in a property of the container object.
In the SetupDeviceSerialID() method we call properties native to the 'container' (such as if it's an internal debug mode) as well as some other objects. What would be the best way to test this scenario where we have objects within objects? Would we mock all the calls, properties, and objects in order to isolate the test for SetupDeviceSerialID()?
Or do we mock the 'componentInterface' that's returned and mock the call for SetupDeviceSerialID() and then test the properties that were changed within SetupDeviceSerialID()?
EDIT
I've been thinking about testing this incorrectly (obviously) and through the answers I've come to realize that I was trying to cram testing for methods executed deeper in the code, into tests for the SetSerialIdForDevice() method.
So as a result,
If a serialID is found, we would set serialfound = true inside of SetupDeviceSerialID().
Is that something we would test here (since we will be testing for serialfound=false), or in a test for SetupdDeviceSerialID()? And would we create a test to see if SetupDeviceSerialID() actually exists on the "componentInterface" component?
I would mock container to have the getComponentRef return a mock object which the method can test against. Mocking each "componentInterface" class needs to be something that happens in their own dedicated unit tests. Don't combine testing responsibilities because its convenient, keep everything as its own unit so no unit test is dependent on another test.
The mores Seams you can put into your code, the easier it becomes to test.
If you can replace the return value of the getComponentRef method with a Test Double, you can write one test that verifies that this method has been invoked correctly and then move on to writing other unit tests that verifies something else.
Ideally, you should only be writing one test that tests any particular piece of behavior.
Assuming you can replace the component variable with a Test Double, you could then verify that the SetupDeviceSerialID method is called correctly.
That, as well as some tets that exercise the error paths, should then conclude the test suite for the SetSerialIdForDevice method.
You can then move on to write a new set of tests that verifies that a particular 'component' implementation works as intended, but those would be separate tests that are independent of the tests that exercise the SetSerialIdForDevice method.