In my unit test case, I'm trying to check if a particular function is being called or not using this:
mock_wait_until_complete.assert_called()
The function wait until complete takes 2 arguments: (uid: string, time: int)
I want to build it in such a way that it passes the test case irrespective of any arguments that are passed.
Is there any way to achieve this?
** Edit
AssertionError:
Expected call: wait_until_complete('bt_url, verify=False)
Actual call: wait_until_complete(<MagicMock name='post().text' id='2039952'>)
So, right now I'm getting this error with this piece of code during testing, but its working exactly how I want it to. So, to basically ignore this error, I want it to accept/assert True no matter what argument is being passed..
In addition to the comments, I solved this particular code by using:
assertEqual(mocked_wait_until_complete.call_count, 1)
This basically checks if the function is called once irrespective of any arguments passed.
Related
I'm currently learning curses in python, and I found this piece of code online that is confusing me.
import curses
def draw_menu(stdscr):
# do stuff
# if you want more code just let me know
def main():
curses.wrapper(draw_menu)
if __name__ == "__main__":
main()
When I run this I don't get the expected missing 1 required positional argument error, since there is no parameter being passed in the curses.wrapper(draw_menu) line. Is this a curses thing? Any help is greatly appreciated.
A function is a datatype, just as much as strings, integers, and so on.
def my_function(txt):
print(txt)
here type(my_function) # => <class 'function'>
You invoke the code inside the function when you call it with parenthesis : my_function('hello') # => prints hello
Until then you can perfectly pass a function as an argument to another function.
And that last one can call the one you passed giving it some parameters.
Like in your case, I'd guess that curses.wrapper() creates a screen interface that it passes as argument your draw_menu() function.
And you can probably use that screen object to build your curse app.
See this : Python function as a function argument?
There's a big difference between curses.wrapper(draw_menu) and curses.wrapper(draw_menu()). curses.wrapper(draw_menu) calls curses.wrapper and passes the function draw_menu into it as an argument. In contrast, curses.wrapper(draw_menu()) would call draw_menu and pass its return value into curses.wrapper.
curses.wrapper will call the function you pass it. From that link:
Initialize curses and call another callable object, func, which should be the rest of your curses-using application.
E.g., it will call draw_menu when curses is completely initialized.
Here is the signature for curses.wrapper from here.
curses.wrapper(func, /, *args, **kwargs)
It says that you need to give curses.wrapper a function reference argument followed by zero or more arguments and keyword arguments. Your code satisfies those requirements.
Python allows function signatures like this to enable developers a lot of flexibility regarding what can be passed in by the caller.
I am able to successfully mock a function, and I am sure that the original is not called. I added a huge print statement to the original function and when I mock it, this print is not called. When I turn the mock back on, the print statement is not called.
However, my assert_called is failing saying it was never called. Has anyone ever experienced something like this?
class FooTestCase(unittest.TestCase):
#mock.patch('MyObj.helper_function')
def test_simple(self, mock_hf):
my_obj = MyObj()
# internally, this class imports HelperModule
# and the method calls helper_function
my_obj.do_something()
mock_hf.helper_function.assert_called()
return
My error response
AssertionError: Expected 'helper_function' to have been called.
Update
I just added the following lines right before the assertion
print mock_cw.method_calls
print mock_cw.mock_calls
method_calls is an empty list, while mock_calls is a list with 1 item which is
[call(arg1_expected_for_helper_fn, arg2_expected_for_helper_fn)]
Yet the assert still fails
Usually an error like this is a result of not patching the correct location. Try to patch the object itself with this:
#patch.object(MyObj, "helper_function")
def test_simple(mock_hf):
...
Since MyObj is (assumed to be) imported at the top of the test file, this patches the method on that object directly.
The issue is that I was checking to see if mock_hf.helper_function was called, but mock_hf is already mapped to the helper_function. I was more or less checking that helper_function.helper_function was called rather than just helper_function.
The assert line needed to be
mock_hf.assert_called()
I see the original poster has done this, but for anyone else stumbling on this as I did...
Don't forget you need to wrap your expected calls in a call object e.g.
mock_logger.assert_has_calls([call(expected_log_message_1), call(expected_log_message_2)])
If you don't do that, it will complain that the expected call did not happen and you will spend ages comparing the output to try and work out why (as I did!).
so this is my function, and it doesn't work.. why?
def Oppnadjur(djurfil):
djurfil = open("djur.txt", "r")
Djur = djurfil.readlines()
Djur.sort()
djurfil.close()
Djurlista=[]
You wrote that your function should receive one parameter, djurfil. However, you clearly did not mean to do that, as you proceed to not use that parameter, overwriting it with a different value. See the Python Tutorial about how to define functions.
The error message you see means that you had called your function as you had intended, with no parameters (Opnnadjur()), but that's not how you had defined it. So Python is looking for the parameter it thinks you should be passing in.
The error would be in your calling code, not the def of the function. You need to call Oppnadjur with one parameter. The error message suggests that you are calling it with zero parameters.
You define your function with one argument (djurfil), but the argument is unused in your function so you can get rid of it.
def Oppnadjur():
djurfil = open("djur.txt", "r")
Djur = djurfil.readlines()
Djur.sort()
djurfil.close()
Djurlista=[]
Writing some unit tests in python and using MagicMock to mock out a method that accepts a JSON string as input. In my unit test, I want to assert that it is called with given arguments, however I run into issues with the assert statement, since the ordering of objects within the dict doesn't matter, besides in the assert statement for the string. Simplified example of what I am trying to achieve below.
mock_funct = MagicMock()
# mocked function called elsewhere
expected = {"a":"a", "b":"b"}
mock_funct.assert_called_once_with(json.dumps(expected))
The above may pass or may fail due to the arbitrary ordering of the keys within the dict when it is dumped to json, ie both '{"a":"a", "b":"b"}' and '{"b":"b", "a":"a"}' are valid dumps but one would fail and one would pass, however I would like to write the test so that either would pass.
Unfortunately, you'll need to do your own checking here. You can get the calls from the mock via it's call_args_list attribute (or, simply call_args in this case since you have already asserted that it is called only once). I'll assume you're using unittest in my example code -- but it should be easy enough to adapt for any testing framework ...
mock_funct.assert_called_once_with(mock.ANY)
call = mock_funct.call_args
call_args, call_kwargs = call # calls are 2-tuples of (positional_args, keyword_args)
self.assertEqual(json.loads(call_args[0]), expected)
I've still used assert_called_once_with to make sure that the function was only called once with a single positional argument, but then I open up the call to look at that argument to check that it is correct.
I am new to Python. I came across a weird case and am not able to figure out what the issue is. I have 2 versions of a function written in Python :-
v1 -
def fileLookUp(fixedPath, version):
if version:
targetFile="c:\\null\\patchedFile.txt"
else:
targetFile="c:\\null\\vulFile.txt"
#some more code follows
and v2 -
def fileLookUp(fixedPath, version):
if version:
print "ok"
else:
print "not ok"
#some more code follows
where the parameter fixedPath is a string that is entered and the parameter version is supposed to be an integer value. The 1st function (v1) does not work as expected, while tje second works perfectly. Both the times the function is called as fileLookUp("c:\\dir\\dir\\", 1).
In the 1st case the error received is :-
fileLookUp("D:\\Celine\\assetSERV\\", 1)
Exception: fileLookUp() takes exactly 2 arguments (1 given)
Please let me know why is the 1st function throwing the exception?
Here is the actual code....
from System.IO import *;
def fileLookUp(fixedPath, version):
if version:
targetFile="c:\\null\\patchedFile.txt";
else:
targetFile="c:\\null\\vulFile.txt";
vulFileHandle=open(targetFile,"a+");
temp=fixedPath;
if not Directory.GetDirectories(fixedPath):
files=Directory.GetFiles(fixedPath);
for eachFile in files:
print eachFile;
hash = Tools.MD5(eachFile);
print hash;
vulFileHandle.write(eachFile+'\t'+hash+'\n');
else:
directory=Directory.GetDirectories(fixedPath);
for folder in directory:
if vulFileHandle.closed:
vulFileHandle=open(targetFile,"a+");
fixedPath="";
fixedPath+=folder;
fixedPath+="\\";
vulFileHandle.close();
fileLookUp(fixedPath);
filess=Directory.GetFiles(temp);
for eachFilee in filess:
if vulFileHandle.closed:
vulFileHandle=open(targetFile,"a+");
print eachFilee;
hashh = Tools.MD5(eachFilee);
print hashh;
vulFileHandle.write(eachFilee+'\t'+hashh+'\n');
if not vulFileHandle.closed:
vulFileHandle.close();
it is simply a recursive code to print out the hash of all files in a directory.
You have a call "fileLookUp(fixedPath);" around line 26 or so (just counted roughly) with only one argument sent in. Your definition doesn't allow that. Send in the version in this call, or give a default value to version in the definition.
The way these functions are written, both of them must be called with two arguments. The error message you're getting indicates that one of them is being called with only one argument. In Python, if you want to make an argument optional, you have to explicitly state what value the optional argument should have if it is not provided. For example, since version is to be an int, and you test it with if version:, a good default value could be 0. You could also use None.
def fileLookUp(fixedPath, version=0):
# etc.
def fileLookUp(fixedPath, version=None):
# etc.
If 0 is a valid version number, and you want to test for whether a value was actually passed, use the second and test against None specifically:
def fileLookUp(fixedPath, version=None):
if version is None:
# etc.
In the (very badly formatted) full exemple, you're making a recursive call to fileLookUp not passing the version argument.