How do you test a referenced class that performs internal operations? - vb.net

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.

Related

Tests retrieved from collection variable - test failures stop subsequent tests from running

I have tests that I want to use in multiple API calls.
Using JavaScript from external files has been an open issue for 6 years now but isn't officially supported (yet). I'm storing tests in collection variables so they can be retrieved in each APIs Tests.
The issue is tests that fail stop execution like a general JS failure.
Tests being stored in collection variables via an API’s Pre-req
In a setup API call I store the shared library of tests via a Pre-request Script. This is working fine.
A "normal" test failure
When a test is coded in an API's Test area, failures don't stop subsequent tests from running.
A failure for a test pulled in from a collection variable
I can pull tests from the collection variable and run them just fine. However when a Chai expectation fails it seems to be treated like a JavaScript failure instead of an test/expectation failure.
The test run fails, subsequent tests for this API don't run nor do other APIs in the collection run.
How can I have tests retrieved from a collection variable run/fail like hard coded tests?
Problem I guess is how you call function from utils
Just utils.payloadIs204, not utils.payloadIs204()
And it works for me
Update reuse with passing parametes.
Tab pre-request
pm.environment.set("abc", function print(text1, text2){
console.log(text1)
console.log(text2)
} + "");
Tab Test
let script = pm.environment.get("abc");
eval((script + "print('name', 'age')"))
The problem was in how I was calling the library function. It works as desired if the library function (with the expectations) is invoked in the anonymous function passed to pm.test(), not be the passed function.

How to restrict test data method call for respective Test method by using TestCaseSource attribute in NUnit

I am using NUnit for the Selenium C# project. In which I have many test methods. For getting data (from excel) I am using a public static method that returns IEnumerable<TestCaseData> which I am calling at test method level as TestCaseSource. I am facing challenges now, as I start executing on the test method it is invoking all the static methods which are there in the project.
Code looks like this:
public static IEnumerable<TestCaseData> BasicSearch()
{
BaseEntity.TestDataPath = PMTestConstants.PMTestDataFolder + ConfigurationManager.AppSettings.Get("Environment").ToString() + PMTestConstants.PMTestDataBook;
return ExcelTestDataHelper.ReadFromExcel(BaseEntity.TestDataPath, ExcelQueryCreator.GetCommand(PMTestConstants.QueryCommand, PMTestConstants.PMPolicySheet, "999580"));
}
[Test, TestCaseSource("BasicSearch"), Category("Smoke")]
public void SampleCase(Dictionary<string, string> data)
{
dosomething;
}
Can someone help me how can I restrict my data call method to the respective test method?
Your TestCaseSource is not actually called by the test method when you run it, but as part of test discovery. While it's possible to select a single test to execute, it's not possible to discover tests selectively. NUnit must examine the assembly and find all the tests before it's possible to run any of them.
To make matters worse, if you are running under Visual Studio, the discovery process takes place multiple times, first before the tests are initially displayed and then again each time the tests are run. This is made necessary by the architecture of the VS Test Window, which runs separate processes for the initial disovery and the execution of the tests.
That makes it particularly important to minimize the amount of work done in test discovery, especially when running under Visual Studio. Ideally, you should structure the code so that the variable parameters are recorded during discovery. The actual data access should take place at execution time. This can be done in a OneTimeSetUp method, a SetUp method or at the start of the test itself.
Finally, I'd say that your instinct is correct: it should be possible to set up a TestCaseSource, which only runs if the test you select is about to be executed. Unfortunately, that's a feature that NUnit doesn't yet have.

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?

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.

Testing loading of a class in ObjectiveC

I have some code in +initialize method of a class that I'd like to test (using simple OCUnit). Namely it's application delegate that sets some user defaults, so my testing would look like this:
Check for absence of values-to-be-set;
Load a class;
Check for presence and correctness of set values;
Do you have any hints on how can I achieve this?
Yup - You can move your defaults initialization implementation out to a separate function, which you call from +[MONObject initialize].
Test the function in a lower level suite which does not load the objc class (MONObject) into the objc runtime.
Then you can test it and destroy it in a separate executable, and rely on that proof in your app level test suite.
When you set "user defaults" defaults it is only used when no other value has been stored in the "user defaults". So, if you call a value from "user defaults" you get the default value unless you have stored value in a previous run (note you have to delete the App on the device because "user defaults" are stored between runs).
You should set defaults for all "user defaults", because it only applies when used for the first time.
I may have misunderstood what you are asking but I think that you are mixing set values in the default and default values that are used when none have ever been set.
I am also confused why you are loading a class in +initialize class method, that gets called before any instance is created?

How to reset the mockrepository object to call the original method after all the calls in mocks.record() are made?

I have a .NET 3.5 Win Form application with three classes login.cs,Main.cs,dBTansaction.cs. I am writing a testcase to for Main.cs which makes calls to dbTransaction.cs. So I mocked to DBTransaction.cs to return diff values for each call and it all works fine. After the testcase is run in my teardown, i close the application for which it calls the login.cs to check if user is allowed to close application. This login.cs also makes call to DBTransaction.cs and since i mocked this class in testcase it throws an exception saying unexpected call.
How do i reset the mock objec to redirect to the original DBTRansactio.cs when called from TearDown.
Thanks
If you're writing a unit test for main.cs, then all of its dependencies (login and dbtransaction) should be mocked. You're already mocking dbtransation. I suggest you mock out your login as well so you don't have to worry about any external dependencies in your tests.