Eruption of Clojure Protocols

Can one of the popular Java phrases, such as EasyMock or Mockito, be used to define Clojure protocols defined using defprotocol? If so, how?

+5
source share
2 answers

You should be able to wind protocols using any mock library. Under the covers, each protocol uses the Java interface as an implementation detail, and you can simply mock that interface.

However, do not do this! Mocking Java is absurdly complicated due to reflection, protection levels, end classes, etc. Every time you want a Clojure object that implements the protocol, just call reify , for example

 (defprotocol Foo (method-a [_]) (method-b [_]))
 -> Foo

 (let [stub (reify Foo (method-a [_] :stubbed))] 
   (method-a stub))
 -> :stubbed

Note that you do not need to stub methods that you do not plan to call.

+9
source

It seems that later versions of Midje provide this functionality pretty well.

-, , (, , Stuart Sierra ). , , , , , stand-in, :

  • , , ( ).
  • , .

Mockito , , .

, , Midje , ... :

(defrecord-openly SideEffectThing [connection]
 ISideEffect
 (persist [this thing] :unfinished)
 (read [this] :unfinished)
)

. Midje , , , .

defrecord-openly, "" Midje:

(fact "you can test in terms of a record methods"
  (let [obj (->SideEffectThing :fake-connection)]
   (user-of-side-effect-thing obj) => 0
   (provided
    (read obj) => -1)
  )
 )

, ( ), defrecord- . SideEffectThing ( ) . , .

, Java Mockito . Java:

interface ISideEffect { int read(); void write(Object something); }
class SideEffectThing implements ISideEffect { ... }

// in test sources:
public class SomeOtherComponentSpec {
   private ISideEffect obj;
   @Before
   public void setup() { obj = mock(ISideEffect.class); }
   @Test
   public void does_something_useful() {
      when(obj.read()).thenReturn(-1);
      OtherComponent comp = new OtherComponent(obj);

      int actual = comp.doSomethingUseful();

      assertEquals(0, actual);
      verify(obj).read();
   }

Java , , , , read() - . Mockito ( ), , , .

Midje . ( ), , , . , ( ), . , , 3 :

(fact "you can test in terms of a record methods"
  (let [obj (->SideEffectThing :fake-connection)]
   (user-of-side-effect-thing obj) => 0
   (provided
    (read obj) => -1
    (read obj) => 6
    (read obj) => 99
    )
  )
 )

, , . . , , .

+2

All Articles