Package: mimid
mimidModern mocking library for Python.⚠️ This project is under heavy development, API could be unstable.InstallationTo installmimid, simply usepip:$ pip install mimidQuick startfrommimidimportmock,every,verify,any,gtdefadd(a:int,b:int)->int:returna+bdeftest_add():add_mock=mock(add)every(add_mock).returns(5)result=add_mock(2,2)assertresult==5verify(add_mock).with_args(any(),gt(0)).called(times=1)FeaturesMimid supports following features:easy mock behaviour configuration and verificationworks with classes and plain functionsfully type hinted - it works with IDE's and type checkersclean API - not too much magicWhy notmock?Python built-inmockmodule is an awesome tool. It's a first choice if you want to mock something in your tests.However it has a few disadvantages:it doesn't work well with modern IDEs (e.g. auto completion) and type checkersit's difficult to define different behaviours for different casesit allows too much freedom, you can do anything with your mock object, even if you didn't define any behaviourInspirationMimid is highly inspired by mocking frameworks from a JVM world, likemockitoormockk.UsageThere are 3 simple steps in themimidmocking workflow:CreationConfigurationVerificationAdditionally you can usematchersin both configuration and verification steps.CreationYou have to usemockfunction to create your mock object. It works both with classes and functions.Class example:frommimidimportmockclassA:deffoo(self,param):passclass_mock=mock(A)Function example:frommimidimportmockdeffoo(param):passfunction_mock=mock(foo)ConfigurationBefore you call your mock (function or method) you have to configure its behaviour. Useeverywith additional
methods (returns,raises, ...) to define how it should works during your test.frommimidimportmock,everydeffoo(param):passfunction_mock=mock(foo)every(function_mock).returns(1)You can also specify arguments which should trigger defined behaviour.frommimidimportmock,everydeffoo(param):passfunction_mock=mock(foo)every(function_mock).with_args(param=2).returns(1)every(function_mock).with_args(param=3).raises(Exception())If you want to define property behaviour you have to usepropfunction:frommimidimportmock,every,propclassA:@propertydefx(self)->int:passclass_mock=mock(A)every(prop(class_mock).x).returns(1)Available configurations:ConfigurationDescriptionreturnsreturn given valuereturns_manyreturn each value from provided listraisesraise given exceptionexecutecall given callableVerificationAt the end of your test you can check if mock was called as expected withverify.frommimidimportmock,verifydeffoo(param):passfunction_mock=mock(foo)...# mock callsverify(function_mock).called(times=2)You can use the samewith_argsalso during verification step:frommimidimportmock,verifydeffoo(param):passfunction_mock=mock(foo)...# mock callsverify(function_mock).with_args(param=1).called(times=2)MatchersYou can use matchers during configuration (with_args) and verification (with_args,called) steps. You can also combine matchers with|or&and negate it with~.Example:frommimidimportmock,every,verify,gt,lt,gtedeffoo(param):passfunction_mock=mock(foo)every(function_mock).with_args(gt(0)).returns(1)result=function_mock(10)assertresult==1verify(function_mock).with_args(gt(5)|lt(15)).called(times=gte(1))captureis a special matcher - it behaves likeany()but additionally it
stores given argument in provided slot.Example:frommimidimportmock,every,slot,capturedeffoo(param):passfunction_mock=mock(foo)param_slot=slot()every(function_mock).with_args(capture(param_slot)).execute(lambda:param_slot.value+1)result=function_mock(1)assertresult==2assertparam_slot.value==1Available matchers:MatcherDescriptionanymatch any valueeqmatch equal valueltmatch lower valueltematch lower or equal valuegtmatch greater valuegtematch greater or equal valuecapturecapture provided argumentAuthorsCreated byKonrad Hałas.