简体   繁体   中英

How can I check if an internal service threw an exception?

I'm trying to write a unit test for a new service. The service returns void and uses other auto-wired services to do some work. I want to test a case where one of the internal services throws an exception which is caught by the top level service under test. How can I verify in the 'then' clause that the internal service threw an exception if it is caught by the service under test?

I would also like to verify that a static method was called to log the result, but I can't see a way to do that with Spock either. These are the only outputs for the service so I would like to verify that they are working.

To address the first part of your question:

Let's assume we have the following structure:

interface ServiceUnderTest {
   void foo()
}
interface InternalService {
   int bar() throws IllegalArgumentException
}

class ServiceUnderTestImpl implements ServiceUnderTest {
    InternalService internalService
    ServiceUnderTestImpl(InternalService internalService) {
       this.internalService = internalService
    }

    void foo() {
        try {
          internalService.bar()
        } catch(IllegalArgumentException ex) {
          println "Got you"
        }
    }
 }

You're testing method foo() in ServiceUnderTest and it returns void

So I suggest creating Stub of Internal Service that throws exception upon invocation of its bar method

The test will check that no exception has been thrown when calling foo (which means that the exception thrown by internal service was caught and handled correctly)

The test can look like this:

class SampleSpockTest extends Specification {
   def "test sample" () {
      given:
        def internalService = Stub(InternalService)
        def subject = new ServiceUnderTestImpl(internalService)
        internalService.bar() >> {throw new IllegalArgumentException("Sample 
           exception")}
      when:
        subject.foo()
      then:
        noExceptionThrown()
     }
 }

I think that you shouldn't check in "then clause that the internal service threw an exception" as you say, actually you're checking the ServiceUnderTest . Its not optimal that it returns void, because you can't really know what did it do, maybe by checking its internal state after the invocation of method foo or something, but at least you can check that the exception was processed if internal service was called and threw and exception.

Regarding the static method mocking, you shouldn't do it probably, mocks do not play well with static calls. You can use "special" tools like PowerMock or PowerMockito, but I believe, they point on a code smell and should be primarily used for legacy code. Its only my opinion, though.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM