python mock patch original function still being called - python-unittest.mock

Kinda new to python unittest mock. I have the following code which mocks a number of functions, then tests and calls main(). The mock items are called from main. However, even though the unitests run successfully the original functions are being called as well. Why is this happening?
#patch('utilities.etl.load')
#patch('utilities.etl.get_joined_data')
#patch('utilities.etl.transform')
#patch('utilities.etl.extract_salary')
#patch('utilities.etl.extract')
#patch('utilities.helper.get_spark_session')
def test_main(self, mock_get_sparksession, mock_extract,
mock_salary, mock_transform,
mock_join, mock_load):
mock_get_sparksession.return_value = self.spark
mock_extract.return_value = self.test_extract
mock_salary.return_value = self.test_salary
mock_transform.return_value = self.test_transform
mock_join.return_value = self.test_join
mock_load.return_value = None
main.main()

Related

Junit - how to get test result as string?

I am trying to test the code and get a result as String to send it to API later.
class FirstClass{
fun main(){
print("Hello world!")
}
}
Test:
ort org.junit.jupiter.api.AfterEach
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import java.io.ByteArrayOutputStream
import java.io.PrintStream
import kotlin.test.assertEquals
internal class FirstClassTest {
private val outContent = ByteArrayOutputStream()
private val errContent = ByteArrayOutputStream()
private val originalOut = System.out
private val originalErr = System.err
#BeforeEach
fun setUp() {
System.setOut(PrintStream(outContent))
System.setErr(PrintStream(errContent))
}
#AfterEach
fun tearDown() {
System.setOut(originalOut)
System.setErr(originalErr)
}
#Test
fun main() {
val SUT = FirstClass()
SUT.main()
val testResult = assertEquals("Hello world!", outContent.toString())
print("Test result: $testResult")
val api = Api()
val apiResult = api.sendResult(testResult.toString())
print("Api result: $apiResult")
}
}
The test is passing, however, I do not see printed messages. How to get a test result as String?
There are several issues here.  The main one is:
The redirection affects your test method too.
Because you've redirected System.out, the print() in your test method goes to outContent, along with the output from FirstClass.main() that you want to test, instead of to the screen or wherever you want it.
I can see two fixes for this.
The quick one is for your test method to output to originalOut:
originalOut.print("Test result: $testResult")
Your test method is in the class which does the redirection, so there's no problem with it knowing about the redirection, and it already has access to originalOut.
However, if you can, I think a better solution is to refactor FirstClass so that it doesn't hard-code the stream it writes to.  For example, the stream could be passed as a parameter; or it could return the string directly (and the caller, in a thin non-tested wrapper, could write it to System.out).
That would be more work, but would make your code more flexible as well as easier to test.
Other issues include:
You're using print() instead of println().
Many streams are line-buffered, writing their output only after a newline, and so you might not see any results if there isn't one.  (And even if you do, all the results would be jammed on a single line!)
You assign the result of assertEquals().
assertEquals() doesn't have a useful return value.  (It return Unit.)  So your code will simply show:
Test result: kotlin.Unit
Instead, like all the assert functions, it throws an exception if the assertion fails.  So there's no point in storing or processing the return value; simply calling the assertion is enough.
— This means that there's usually no need to call print()/println() from your test method anyway!  If there's a failure, it'll be obvious: running from the command line will stop with an exception message and stack trace; IntelliJ shows a big red mark next to that test; Maven and Gradle will stop the build (after all tests have run), showing the number of failures.  So if everything continues smoothly, you know the tests have passed.
Api is not defined.
The code you posted above won't compile, because it doesn't include a definition or import for Api.  (Those last lines can be removed, though, without affecting the question.)
main() is a confusing name for a test.
The unit testing framework will find and run all test methods annotated with #Test.  A test class will often contain many different test methods, and it's usual to name them after the aspect they're testing.  (That makes any failures clearer.)  Calling it main() not only fails to describe what's being tested, but also suggests that the method will be run from outside the testing framework, which would probably not behave properly.

jasmine testing on external library

I am attempting to do some basic testing using jasmine. I use an external library & what I intend to do is spy/mock the method calls on the library object (d3) and make sure appropriate methods are called on d3.
var d3Spy = jasmine.createSpyObj('d3', ['select']);
spyOn(window, 'd3').andReturn(d3Spy);
expect(d3Spy.select).toHaveBeenCalled();
When 'select' is being called on the object, I get this error.
TypeError: Object function () {
spyObj.wasCalled = true;
spyObj.callCount++;
var args = jasmine.util.argsToArray(arguments);
spyObj.mostRecentCall.object = this;
spyObj.mostRecentCall.args = args;
spyObj.argsForCall.push(args);
spyObj.calls.push({object: this, args: args});
return spyObj.plan.apply(this, arguments);
} has no method 'select'
What am I doing wrong?
The failure in your code is the following
spyOn(window, 'd3').andReturn(d3Spy);
This line wil return the spy only when you call d3(). So it replace the d3 object with a function that when its called returns the {select: jasmine.createSpy()}. But using d3 you will never call d3() cause select is a static member of d3
So the solution is just to spy on `d3.select'
spyOn(d3, 'select')
Btw. the problem with libs like D3 that use heavy chaining is, that its hard to mock. So the select spy in your example has to return the an object which fits the d3 Selections object and so on. So sometimes it would be easier to not mock out everything.

Call Closure defined in other script

What is the correct and simplest way to access a closure defined within another script in Groovy. This might not be the best design, but I have a closure defined in
SomeScript.groovy
bindingC = {
...
}
def localC = {
...
}
OtherScript.groovy
SomeScript s = new SomeScript()
s.bindingC(...);
s.localC(...);
Note: SomeScript.groovy is program logic and OtherScript.groovy is unit testing logic. They are both in the same package and I'm able to access methods in SomeScript already.
There are two ways (i'm aware) you can use to achieve what you want; you can either instantiate the SomeScript and run its contents or you can evaluate SomeScript using groovy shell. The script needs to be executed so the variable will be created in the binding:
SomeScript.groovy:
bindingC = {
110.0
}
OtherScript.groovy solution 1:
s = new GroovyShell().evaluate new File("SomeScript.groovy")
assert s.bindingC() == 110.0
OtherScript.groovy solution 2:
s2 = new SomeScript() // SomeScript is also an instance of groovy.lang.Script
s2.run()
assert s2.bindingC() == 110.0

QtWebKit QApplication call twice

I am calling a scraping class from Flask and the second time I instantiate a new Webkit() class (QApplication), it exits my Flask app.
How can I re-run a Qt GUI app multiple times and have it contained so it does not shut down the "outer" app?
Further clarification, Qt is event drive and calling QApplication.quit() closes not only the event loop but Python as well. Not calling quit() though never continues executing the rest of the code.
class Webkit():
...
def __run(self, url, method, dict=None):
self.qapp = QApplication(sys.argv) # FAIL here the 2nd time round
req = QNetworkRequest()
req.setUrl(QUrl(url))
self.qweb = QWebView()
self.qweb.setPage(self.Page())
self.qweb.loadFinished.connect(self.finished_loading)
self.qweb.load(req)
self.qapp.exec_()
def finished_loading(self):
self.qapp.quit()
The only (hacky!) solution so far is for me is to add this to the WebKit() class:
if __name__ == '__main__':
....
and then parse the result from the Flask app with this:
return os.popen('python webkit.py').read()

What is the Use of Repeat.Any() in Expect.Call while using Rhino Mocks Test framework

When I use Repeat.Any() it doesn't show any error though I don't call GetMood() Method ,but if i don't use n doesn't call GetMood then it shows Excpetion of type ExpectationViolationException.Can somebody tell me what is the use of repeat.any().
MockRepository mocks = new MockRepository();
IAnimal animal = mocks.DynamicMock<IAnimal>();
using (mocks.Record())
{
//Expect.Call(animal.GetMood()).Return("punit");
Expect.Call(animal.GetMood()).Return("Punit").Repeat.Any();
}
//animal.GetMood();
mocks.ReplayAll();
mocks.VerifyAll();
Repeat.Any specifies that GetMood() can be called 0 or more times and that it should return "Punit" if it is called.
The line
Expect.Call(animal.GetMood()).Return("punit");
implies that GetMood must be called exactly once. This is the same as Repat.Once.
You may also use AtLeastOnce, Times, Twice, and Never.