note35 / sinon

Standalone and test framework agnostic Python test spies, stubs and mocks (pronounced "sigh-non").
BSD 2-Clause "Simplified" License
13 stars 4 forks source link

Cannot chain throws #40

Closed jonathan-benn closed 6 years ago

jonathan-benn commented 6 years ago
stub = sinon.stub().onFirstCall().throws(BaseException('Hello World')).onSecondCall().returns(42)
stub() # we expect an exception 'Hello World', instead we get an error
stub() # we expect a return value of 42, instead we get an error
stub() # we expect a return value of None, instead we get an error
note35 commented 6 years ago

I found another issue by running this code. (python3.6.2 and python2.7.10)

Traceback (most recent call last):
  File "test.py", line 13, in <module>
    stub() # we expect an exception 'Hello World', instead we get an error
  File "/Users/kir/python-dev/sinon/sinon/lib/base.py", line 134, in __call__
    self.pure_count = self.pure_count + 1
AttributeError: '_SinonStubCondition' object has no attribute 'pure_count'

In my first glance, I guess something wrong while working on remove dirty hack or __call__.

jonathan-benn commented 6 years ago

Hi Kir,

I'm investigating this issue now, I think I've figured it out and I will submit a solution soon.

I've got a question for you: what is the point of the args_type "MODULE"? It doesn't seem to do anything useful. It can't accumulate a callCount, for example. All it seems to do is create a lock so a second spy/stub can't be created. But what is the point of that?

Thanks,

--Jonathan

note35 commented 6 years ago

"MODULE" was supposed to be used to inspect a "module/class".

For example:

>>> spy_os = sinon.spy(os)
>>> os.system('ls')
>>> os.getenv('xxx')
>>> spy_os.callCount
2

I have implemented part of those features before, but later removing most of them because it's not implemented by SinonJS (iirc, it's because of the limitation of Javascript). And as the result, some code are remained.

You can either choose to keep them or get rid of them if needed.

jonathan-benn commented 6 years ago

Hi Kir,

Ok, thanks for the clarification. I'll be considering the args_type = 'MODULE' to be out-of-scope for testing, since it's an incomplete feature.

I've figured out the issue. The problem was that in some cases the end user was receiving a _SinonStubCondition object, and that this object was not initializing base.py attributes like pure_count and args_type.

Here's the solution I'm proposing:

  1. Remove pure_count, since it seems that it hasn't been necessary since we added the SpyCall class
  2. Add @property methods to _SinonStubCondition that indirect to the _copy.

Best Regards,

--Jonathan