TDD: Should I define everything that my code should not do?

Problem

I use Test-Driven Development and find it difficult for my tests to define my code well enough. A simple example of my problem is as follows.

I have MyObjectone from which I want to call either methodA(), or methodB(), belonging OtherObject, depending on which argument MyObjectgets on its own callMethod(int).

Expected code (and desired functionality)

This is essentially what I want to make the code, but first I want to execute it.

public class MyObject {

    private final OtherObject otherObject;

    public MyObject(OtherObject otherObject) {
        this.otherObject = otherObject;
    }

    public void callMethod(int i) {
        switch (i) {
        case 0:
            otherObject.methodA();
            break;
        case 1:
            otherObject.methodB();
            break;
        }
    }
}

Writing this test first

To do this, I'm starting with the writing test - check that the call callMethod(0)is invoked methodA(). I use JUnit and Mockito.

public class MyObjectTest {

    private final OtherObject mockOtherObject = mock(OtherObject.class);
    private final MyObject myObject = new MyObject(mockOtherObject);

    @Test
    public void callsMethodA_WhenArgumentIs0() {
        myObject.callMethod(0);
        verify(mockOtherObject).methodA();
    }
}

/, , , MyObject :

public void callMethod(int i) {
    otherObject.methodA();
}

- callMethod(1)

@Test
public void callsMethodB_WhenArgumentIs1() {
    myObject.callMethod(1);
    verify(mockOtherObject).methodB();
}

:

public void callMethod(int i) {
    otherObject.methodA();
    otherObject.methodB();
}

, , . , ? , . , , , .

2 , , , , , , . , , .

, 3 - 3 - 6, , 2 ? ( , .)

, .

if switch, .

+4
3

, , . . , - , . . , , , :

public void save(){
  if(isDirty)
     persistence.write(this);
}

. TDD . , TDD. , . . , , .

( , ). , case , :

public class MyObject {

    private final OtherObjectFactory factory;

    public MyObject(OtherObjectFactory factory) {
        this.factory = factory;
    }

    public void callMethod(int i) {
        factory.createOtherObject(i).doSomething();
    }
}

public abstract class OtherObject{
    public abstract void doSomething();
}

public class OtherObjectFactory {
    public OtherObject createOtherObject(int i){
        switch (i) {
        case 0:
            return new MethodAImpl();
        case 1:
            return new MethodBImpl();
        }
    }
}

, , ; . : OtherObjectFactory OtherObject. MyObject, ; . , , .

, , , . - . , , , , . .

+3

, . , , , .

  • callMethod(0)?
  • callMethod(1)?

methodA methodB, , . ( -) callMethod? callMethod?

methodA - , callMethod, . , callMethod(0) , . , callMethod(1) , .

+4

. TDD ( Devil Advocate, ) .

Seemann , , , . , Mockito , , Moq, mockOtherObject , methodB() .

, " , ", , - . , , - , / , , , , .

- - Refactor TDD.

, switch . , ? , , callMethod(),

  • MyObject instantiator ( OtherObject)

  • callMethod() ( i, )

, - i , ( @tallseth Factory ).

If you do this, OtherObjectyou should no longer have 2 methods - the operator switchand the Devil's Advocate error disappear altogether.

+1
source

All Articles