Python 3 unit-testing, create mock of singleton class function - python

I'm working on creating unittests for my project.
I have a class called TimerHandler that needs to be tested. This class uses a class called AudioHandler. Both of these classes are singletons. see code below.
timer_handler.py
class TimerHandler(metaclass=Singleton):
def play(self):
# some code that needs to be tested
AudioHandler().start()
audio_handler.py
class AudioHandler(metaclass=Singleton):
def start(self):
# some code that connects with an audio device
I'm trying to mock the start method of AudioHandler so it will just return None and won't try to connect to an audio device. The unittest looks like this:
#patch.object(AudioHandler, 'start', return_value=None)
def test_play_pause(self, start):
self.timer_handler.play()
The problem is that it is still running the code in the original start function in AudioHandler.
How can I write a test function that removes/mocks the functionality of the start function in AudioHandler?
Thanks in advance

You should mock a class from a module path where you are importing it
#patch('timer_handler.AudioHandler')
And after that, you can add your method to the mock object
Please read
https://docs.python.org/3/library/unittest.mock.html#where-to-patch

Related

Is there a magic method to know that a base class is used through inheritance?

I'd like to describe my problem with code to make it clear:
class MyBaseClass(object):
def __init__(self):
print 'foobar'
def __call__(self):
print 'spameggs'
def __is_used__(self): # This is only a pseudo method
print 'I\'m being used! - MyBaseClass'
class MySubClass(MyBaseClass):
def __init__(self):
print 'monty python'
Now I'd like to know if there is a similar magic method __is_used__ for a class object to know if it is being use as a parent/base class of another class (sub)?
Example usage:
class_a = MySubClass()
# Output
# monty python
# I'm being used! - MyBaseClass
Use Case
To avoid confusion (I apologize). A best example would be a mixin. Example an S3Mixin.
An S3Mixin has a capabilities to upload and download file to S3 buckets.
class S3Mixin(object):
def upload(self):
def download(self):
Now i want to use it to ImageFile and VideoFile classes.
class ImageFile(S3Mixin):
# omitted lengthy properties
class VideoFile(S3Mixin):
# omitted lengthy properties
Now each object has a function to use the s3 basic functionalities. Now the real problem arise when I try to use another module inside a S3Mixin which cause a circular dependency issue. Now to avoid it I have to import it inside each function of S3Mixin. I tried putting it on the __init__ method and __call__ method which is obviously not going to work.
I don't want to do that. Instead I wanted to know if there is available method so I can import all the conflicted module preferable on a magic method of an S3Mixin.
Note:
I'm not asking for a checking of a class that is a subclass of another class. That is far from the question. I would like to know if there is a MAGIC METHOD so i can further create a logic in it when a base class is used.

Mocking Classes in Python with unittest

I'm trying to make a mock of a class with unittest.mock.
I have the following structure of packages and modules:
services
service_one.py
repository
repository_mongodb.py
test
services
test_service_one.py
The class repository_mongodb.py is used inside the class service_one.py (by importing the class).
This is the code for the files.
File repository_mongodb.py
class RepositoryMongoDB:
def __init__(self):
self.library = []
def save(self, thing):
self.library.append(thing)
return True
File service_one.py
from repository.RepositoryBookList import RepositoryBookList
class ServiceRodri:
def __init__(self):
self.repository = RepositoryMongoDB()
def save_service(self, thing):
# Do validation or something else
return self.repository.save(thing)
Now I want to try to make a mock of the class ServiceRodri, and here's what I do.
import unittest
from unittest.mock import patch
from service.service_one import ServiceOne
class ServiceOneTest(unittest.TestCase):
def setUp(self):
self.service_one = ServiceOne()
#patch('service.service_one.RepositoryMongoBD')
def test_get_one_book_if_exists_decorator(self, mock_repo):
mock_repo.save.return_value = "call mock"
result = self.serviceRodri.save_service("")
self.assertEquals("call mock", result)
I want that when I call the method "save" of the class RepositoryMongoBD to return the result I'm assigned to it. But this doesn't happen.
I've also tried to do it this way.
#patch('repository.repository_mongodb.RepositoryMongoDB')
def test_get_one_book_if_exists_decorator(self, mock_repo):
mock_repo.save.return_value = "call mock"
result = self.serviceRodri.save_service("")
self.assertEquals("call mock", result)
But it doesn't work either.
But if I try to mock the function save() this way.
#patch('service.service_one.RepositoryMongoDB.save')
def test_get_one_book_if_exists_decorator_2(self, mock_repo):
mock_repo.return_value = "call mock"
result = self.serviceRodri.save_service("")
self.assertEquals("call mock", result)
Works correctly!!! I understand what it's doing is when the call save() is found in service_one module, it is replaced by the mock.
What would be the right way to do it? (and the best way)
I'm a begginer in the world of python. I have searched and read many post, but all the examples shown are very easy (like sum() method). I've tested in other languages but never in Python.
If you insist on using patch, your final attempt is the right way.
The reason the previous attempts don't work is because the patch is applied after the import, so you're not patching the object you think you are.
I've been working with patch for a long time and this still bites me occasionally. So I recommended using simple constructor based dependency injection.
In service_one
class ServiceOne:
def __init__(self, respository):
self.repository
Initialize this with service_rodri = ServiceRodri(RepositoryMongoDB()), maybe in the __init__ file or something. Then in your test, you can create this mock in your setup.
class ServiceOneTest(unittest.TestCase):
def setUp(self):
self.repository = MagicMock()
self.service_one = ServiceOne(self.repository)
N.B. patching vs. dependency injection:
Patching will also couple the tests to the import structure of your program. This makes safe refactoring that alters the structure of your modules strictly more difficult. It's best used with legacy code when you need to get some tests in place before making changes.

how to pass a class to be tested to an unit test class

I have a class and I need to test it
class ToBeTested():
def my_method():
pass
I have designed some unittests in python.
import unittest
class MyFirstUnitTest(unittest.TestCase):
def setUp(self):
# prepare some data
# run a method
# collect results
def test_one_assumption_about_results(self):
#self.assertEqual(...)
def test_another_assumption_about_results(self):
#self.assertEqual(...)
if __name__ == '__main__':
unittest.main()
I have designed this code looking at the examples.
Now I do not understand how to interface it the tesing class MyFirstUnitTest with the classe to be tested ToBeTested?
By inheritance?
class MyFirstUnitTest(unittest.TestCase,ToBeTested):
######
By creating a object of class ToBeTested as static member of
MyFirstUnitTest class definition?
class MyFirstUnitTest(unittest.TestCase):
mytestobj=ToBeTested()
def setUp(self):
By creating a object of class ToBeTested within each of the test
cases of MyFirstUnitTest class definition?
class MyFirstUnitTest(unittest.TestCase):
def setUp(self):
###
def test_one():
mytestobj=ToBeTested()
def test_two():
mytestobj=ToBeTested()
please suggest alternatives and why you would prefer any of them
There is a drawback to using inheritance and static member instead of creating a new object for every test: If tests change the state of the object, then the tests influence each other with their side effects. This gets even worse if the order of the test method calls are not guaranteed and changes (say, you rename a test and suddenly a different test case fails - these things have happened before!)
Additionally, having your test case inherit from the SUT (subject under test) means you only get to test one constructor.
I don't see any advantage to having the testcase inherit from the SUT, especially in python where there are no private members. If for some reason inheritance is necessary for the test (which sometimes IS the case), then having a seperate TestAdapter class that inherits and is instantiated by the test is the best practice.
There are other questions with answers which go more in depth:
https://softwareengineering.stackexchange.com/questions/366425/making-a-test-fixture-inherit-from-the-sut-class
https://softwareengineering.stackexchange.com/questions/154144/how-to-define-implementation-details
You can create an instance of your class(es) in your setup if it will not have to be reinstantiated.
And if you have to create a new instance in every test then just create a new instance in every test.

Python - how to clear class variables automatically when class variables are resource

I have a problem with dealing with class variables in Python. I have a code as the following.
class TempClass:
resource = xlwings.Book() # xlwings is a library manipulating Excel file.
#...
Here, to clear 'resource', I need to execute
resource.close()
Is there any built-in function called when a class (not object) is cleared, so that I can write the above code in that function? Or is there any way to clear 'resource'?
My Python version is 3.6
Don't use a class variable. A class variable is alive as long as the class exists probably as long as your python interpreter isn't shutdown.
Normally with ressources that need to be closed you can simply use a contextmanager (for example contextlib.closing):
import contextlib
# I don't have xlwings so I create some class that acts like it:
class Book(object):
def __init__(self):
print('init')
def close(self):
print('close')
The actual "context" can be created and used like this. Inside the block the resource is alive and it's closed after the block ends. I use prints to show where each method is called:
print('before the context')
with contextlib.closing(Book()):
print('inside the context')
print('after the context')
Which prints:
before the context
init
inside the context
close
after the context

python: How do I dynamically create bound methods from user supplied source code?

I would like to construct a class in python that supports dynamic updating of methods from user supplied source code.
Instances of class Agent have a method go. At the time an instance is constructed, its .go() method does nothing. For example, if we do a=Agent(), and then a.go() we should get a NotImplementedError or something like that. The user then should be able to interactively define a.go() by supplying source code. A simple source code example would be
mySourceString = "print('I learned how to go!')"
which would be injected into a like this
a.update(mySourceString)
Further invokations of a.go() would then result in "I learned how to go!" being printed to the screen.
I have partially figured out how to do this with the following code:
import types
class Error(Exception):
"""Base class for exceptions in this module."""
pass
class NotImplementedError(Error):
pass
class Agent(object):
def go(self):
raise NotImplementedError()
def update(self,codeString):
#Indent each line of user supplied code
codeString = codeString.replace('\n','\n ')
#Turn code into a function called func
exec "def func(self):\n"+' '+codeString
#Make func a bound method on this instance
self.go = types.MethodType(func, self)
QUESTIONS
Is this implementation sensible?
Will this implementation incur unexpected scope issues?
Is there an obvious way to sandbox the user supplied code to prevent it from touching external objects? I can think of ways to do this by supplying sets of allowed external objects, but this seems not pythonic.
Possibly useful SO posts
What's the difference between eval, exec, and compile in Python?
Adding a Method to an Existing Object
(I am working in python 2.6)

Categories

Resources