2016-10-07 6 views
0

[10/7/06 4:00 편집 된 예제 코드] 데이터베이스를 건드리지 않고 코드를 테스트하려고합니다. 그러나 조롱 된 메서드가 실제로 나타납니다. 라는. 여기에 단순화 된 설정입니다 :JMockIt 모의 메서드가 모의가 아닙니다

class DBRow { 
    public DBRow() { } 
    public DBRow(Object obj) { 
     initialize(obj); 
    } 
    public void insert() { 
     actuallyAddRowToDatabase(); 
    } 
} 

class MyObject extends DBRow { 
    MyObject(Object obj) { 
     super(obj); 
    } 
    public void insert(Object obj) { 
     doSomething(obj); 
     insert(); 
    } 
} 

class Factory { 
    static MyObject createObject(Object obj1, Object obj2) { 
     MyObject newObj = new MyObject(obj1); 
     newObj.insert(obj2); 
     return newObj; 
    } 
} 

내가 실제 데이터베이스에 삽입을 방지하기 위해 삽입 작업을 조롱하고 싶었다, 그래서 나는이 같은 시도 :

@Test 
public void testCreation() { 
    new Expectations(MyObject.class) { 
     MyObject mock = new MyObject(null) { 
      @Mock 
      public void insert(Object obj) { } 
     }; 
    { 
     new MyObject(anyString); result = mock; 
    }}; 

    MyObject test = Factory.createObject("something", "something else"); 
} 

을하지만 실제 insert(Object)가 나타납니다 여전히 불리고있다. 모든 인스턴스가 조롱을 당할 수 있도록 클래스가 조롱되었음을 지정합니다. 그리고 insert 메소드가 조롱 받아야한다고 지정하고 있습니다. 그렇다면 실제 메소드가 호출되는 이유는 무엇입니까?

위의 두 번째 문제가 있습니다. 위와 같이 Expectations 블록 안에 모의 클래스를 정의하면 Row(Object) 대신 Row() 생성자 만 호출되어 개체가 올바르게 초기화되지 않은 것처럼 보입니다. 나는 이것을 @BeforeTest 메쏘드로 옮기고 거기에서 그 클래스를 인스턴스화하여 이것을 고쳤다. 여기처럼 그 모습입니다 :

private MyObject mock; 

@BeforeTest 
public void beforeTest() { 
    new MockUp<MyObject>() { 
     @Mock 
     public void insert(Object obj) { } 
    }; 
    mock = new MyObject("something"); 
} 

@Test 
public void testCreation() { 
    new Expectations(MyObject.class) {{ 
     new MyObject(anyString); result = mock; 
    }}; 

    MyObject test = Factory.createObject("something", "something else"); 
} 

그래서이 올바른 생성자를 호출 할 얻을 것으로 보인다,하지만 여전히 insert()이뿐만 아니라 호출되는 것으로 보인다. 어떤 통찰력? 당신은 당신의 즉 fucntion private MyObject mock;하지만, 실제 개체 test 전화를 조롱 객체를 사용하지 않는

답변

0

마지막으로 올바른 생성자가 호출되고 실제 데이터베이스 작업이 발생하지 않도록 테스트를 작성할 수있었습니다. 내가 부딪히는 문제의 일부는 Expectations 블록의 메서드 중 하나가 내가 관심이없는 매개 변수에 대해 예상했던 것보다 다른 개체를 얻고 있다는 것입니다. 그리고 내 문제의 다른 부분이 섞여 있다고 생각합니다. MockUp 클래스와 Expectations 녹음의 역할.

테스트중인 코드는 변경되지 않았습니다. 여기 내 간단한 예는 편의를 위해 다시의 :

Object something; 
Object somethingElse; 

@BeforeTest 
public void beforeTest() { 
    new MockUp<MyObject>() { 
     @Mock 
     public void insert() { } // override the "actual" DB insert 
    };       // of Row.insert() 
} 

@Test 
public void testCreation() { 
    MyObject mock = new MyObject(something); // object correctly init'd 
               // by Row.initialize(Object) 
    new Expectations(MyObject.class) {{ 
     new MyObject(something);  result = mock; 
     mock.insert(somethingElse); 
    }}; 

    MyObject test = Factory.createObject(something, somethingElse); 
} 

중요한 점은 제가 DB를 오버라이드 (override) 할 수있는 모형 클래스를 생성)이 있음을했다 :

여기
class DBRow { 
    public DBRow() { } 
    public DBRow(Object obj) { 
     initialize(obj); 
    } 
    public void insert() { 
     actuallyAddRowToDatabase(); 
    } 
} 

class MyObject extends DBRow { 
    MyObject(Object obj) { 
     super(obj); 
    } 
    public void insert(Object obj) { 
     doSomething(obj); 
     insert(); 
    } 
} 

class Factory { 
    static MyObject createObject(Object obj1, Object obj2) { 
     MyObject newObj = new MyObject(obj1); 
     newObj.insert(obj2); 
     return newObj; 
    } 
} 

내가 궁극적으로 테스트 코드와 함께 결국 무엇을 본질적이다 B) 내 기대치를 기록하기 위해 부분적으로 조롱 된 인스턴스의 로컬 인스턴스를 생성했습니다.

0

,

MyObject test = new MyObject("something", "something else"); 

전화 mock 대신 testtestStuff().

모든 인스턴스가 자동으로 조롱되지 않으므로 조롱 된 인스턴스로 작업해야합니다.

+0

testStuff()은 문제되지 않습니다. 사실, 나는 그것을 나의 모범에서 제거 할 것이다. 문제는 건설 중 insert()입니다. 희망을 갖고 명확하게하기 위해 예제를 편집 할 것입니다. 그러나 "모든 인스턴스가 자동으로 조롱되지 않습니다."라고 말하면서 "Class 객체가 [Expectations 생성자]에 제공되면 ... 지정된 클래스의 모든 인스턴스는 조롱 된 인스턴스로 간주됩니다 ". 당신의 진술을 명확히 할 수 있습니까? – Didjit

+0

견적을 제출 한 문서를 가리 키십시오.'기대'는 조롱 된 인스턴스에 대한 호출에 대한 기록 단계입니다. 그것의 조롱 된 객체 생성 단계. '새로운 MockUp' 또는'Mock'과'jectable' –

+0

을 사용하여 만들어진 조롱 된 객체들 또한 코드를 읽는 데 매우 혼란 스럽습니다. MyObject 정의에는 오직 하나의 생성자 인 MyObject (Object obj) 만 있지만 테스트 코드에서는 new MyObject ("something", "something else")를 사용하므로 내가 무엇을 찾고 있는지 잘 모르겠습니다 에서. 당신의 실제 메소드가 호출되고 있다면, 당신은 실제 객체에서 메소드를 호출하고 가짜 메소드에서는 호출하지 않는다. –