I have a function in one of my chaincode contracts that calls the Golang SDK's stub.InvokeChaincode function in order to call another chaincode and get it's response before continuing with the currently invoked function.
When I try to unit test this function using the mock stubs from the github.com/hyperledger/fabric/core/chaincode/shim package I get memory errors because of this call to invoke an external secondary chaincode function.
Is there a way to unit test functions that have this built in?
Related
I have an Azure Function which is triggered by an Azure Service Bus Queue.
The function is below.
How this Run method can be unit tested?
And how an integration test can be done by starting with AddContact trigger, checking the logic in the method and the data being sent to a blob using the output binding?
public static class AddContactFunction
{
[FunctionName("AddContactFunction")]
public static void Run([ServiceBusTrigger("AddContact", Connection = "AddContactFunctionConnectionString")]string myQueueItem, ILogger log)
{
log.LogInformation($"C# ServiceBus queue trigger function processed message: {myQueueItem}");
}
}
I had the exact same doubts.
Adding Unit Tests is not too complicated, at the end of the day, its a function, so all we got to do is to call the Azure Function with the correct string, for parameter string myQueueItem.
Adding Integration tests needs some additional ground work. In the Github project, the author uses the TestFunctionHost class from Azure/azure-functions-host project.
I tried following this strategy, but the amount of code needed to setup all these is uncomfortably high for my liking. Not a lot of it is well documented, and some of the stuff needs developers to use Azure App Services myGet feed.
I wanted a simpler approach, and thankfully I found one.
Azure Functions is built on top of the Azure WebJobs SDK package, and leverages its JobHost class to run. So in our integration tests, all we need to do, is to setup this Host, and tell it where to look for the Azure Functions to load and run.
IHost host = new HostBuilder()
.ConfigureWebJobs()
.ConfigureDefaultTestHost<CLASS_CONTAINING_THE_AZURE_FUNCTIONS>(webjobsBuilder => {
webjobsBuilder.AddAzureStorage();
webjobsBuilder.AddServiceBus();
})
.ConfigureServices(services => {
services.AddSingleton<INameResolver>(resolver);
})
.Build();
using (host) {
await host.StartAsync();
// ..
}
...
Once this is done, we can send messages to ServiceBus and our Azure Functions will get triggered. Once can even set breakpoints in the Functions getting tested and debug issues!
I have blogged about the whole process here and I have also created a github repository at this link, to showcase test driven development with Azure Functions.
How this Run method can be unit tested?
The method is a static public method. You can unit test it by invoking the static method AddContactFunction.Run(/* parameters /*); You will not need a Service Bus namespace or a message for that matter as your function expects to receive a string from the SDK. Which you can provide and verify the logic works as expected.
And how an integration test can be done by starting with AddContact trigger, checking the logic in the method and the data being sent to a blob using the output binding?
This would be a much more sophisticated scenario. This would require to run Functions runtime and generate a real Service Bus message to trigger the functions as well as validate that the blob was written. There's no integration/end-to-end testing framework that is shipped with Functions and you'd need to come up with something custom. Azure Functions Core Tools could be helpful to achieve that.
We have an AWS Lambda running in Go, and upon initialisation runs the following to initialise AWS X-Ray
err := xray.Configure(xray.Config{
LogLevel: "info",
ServiceVersion: "1.2.3",
})
In a seperate repository, we have a utils repository which exposes a HTTP library for our internal stuff. This is imported as a git submodule to all other Lambdas. The code is as follows:
ctx, subseg := xray.BeginSubsegment(incomingContext, "Outbound HTTP call")
client := xray.Client(&http.Client{Transport: tr})
// further down
client.Do(req)
// finally
subseg.Close(resp)
This works as expected when deployed on AWS, producing a nice graph.
The problem is running unit tests on the utils repository. In the context of that repository alone, X-Ray has not been configured, so on the BeginSubsegment call I get a panic:
panic: failed to begin subsegment named 'Outbound HTTP call': segment cannot be found.
I want to gracefully handle the case when X-Ray has not been configured, log it, and carry on execution regardless.
How can I ensure to properly error handle the call to BeginSubsegment when it does not return an error object?
In the case of lambda this code executes without any panic is because lambda creates a facade segment and then your code will be creating subsegments. In the non lambda environment you will have to create a segment first before creating a subsegment. If you don't then it will generate a panic. Now, If you want to log this panic and continue executing your unit tests then I would recommend you to set AWS_XRAY_CONTEXT_MISSING environment variable to LOG_ERROR. It will basically log your panic and continue executing your unit tests.
I am currently working on a Service Fabric project, where in one of our reliable actors we make calls to a SOAP service. For these calls we read a couple of parameters from the Actor's Settings.xml and also - the SOAP endpoint address and binding information from the App.config file (actually the latter is done implicitly by the generated service proxy class for the SOAP service).
Now I am trying to get the unit testing work with xUnit + ServiceFabric.Mocks. To test an Actor specific method I go through:
1) Creating a "MockCodePackageActivationContext"
2) Creating a "StatefulServiceContext" using the instance of the activation context in step 1.
3) Instantiate the Actor with the code below
MyActor target = new MyActor(
new ActorService(
context: serviceContext,
actorTypeInfo: ActorTypeInformation.Get(typeof(MyActor)),
stateManagerFactory: (actorBase, stateProvider) => new MockActorStateManager()
),
new ActorId(Guid.NewGuid())
);
4) I call target.MyMethod() which breaks due to inability to read config info either from the Settings.xml or the App.config file
I made a test where target.MyMethod_Test() does not read anything from config and it was successful.
Anyone who stumbled upon similar thing? How did you solve it?
You could create a separate class that provides configuration data. Create an interface for it and then inject it in the Actor constructor, in Program Main. (Passing the service context into the new class for example.)
Also create a mock implementation of the interface and pass that one to the Actor for testing purposes.
I have one SoapUI Mock service (served as http://localhost:8454/MyMock) with several operations MockOpA, MockOpB, MockOpC... each of them with his particular unic response.
Is there a way to invoke a particular operation adding it to the URL I used inside the Java code that calls the Mock Service?
Something like http://localhost:8454/MyMock/MockOpA.
I see a lot of examples of one operation several responses; but none of several operations exposed by the same Mock Service.
I have found what I need .....
How to make an AngularJS $http call time out in an unit test so I can test my code behavior in case of network timeouts? I've found nothing in $httpBackend object, also experimenting with $timeout itself didn't yield results. My tested code uses $http to make requests and $timeout to schedule retries, although I think it's not relevant as I can't force a single call to timeout.
The code that demonstrates the issue: http://jsfiddle.net/5xE8d/5/
I am aware that this answer does not really directly answer the question as asked, but might solve the problem.
"Letting the $http time out" tests the wrong thing. Your jsFiddle directly tests that the timeout happens after your configured time. That is not a unit test.
The functionality you are testing through that is that $http works correctly in that it triggers error callbacks after the configured time. $http however is not the system under test.
As a rule of thumb, for a unit test you should assume that dependencies work as specified. You should assume that the $http service triggers the error callback after the time you configure.
This reduces the problem to these two tests:
Ensure you configure the timout correctly for the call, and
ensure that your callback performs the correct actions.
If you insist on making sure that the integration of the $http dependency and your code works correctly, that would belong into an integration test, or in the angular world an E2E test.
Otherwise you can mock out $http and check that the arguments you receive have timeout: 5000 set on them. For the other case you can again mock $http and capture the callback you give to error(), calling that directly in your test.