2016-10-07 3 views
0

[10/7/06 4:00 Редактированный примерный код] Я пытаюсь протестировать некоторый код (используя JMockIt с TestNG), не касаясь базы данных, но кажется, что издевавшийся метод по-прежнему на самом деле называется. Вот упрощенная установка:JMockIt Mocked Method not Mocking

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) является все еще вызываемый. Я указываю, что класс издевается над тем, чтобы все экземпляры были издевались, не так ли? И я указываю, что метод вставки следует издеваться, так почему бы вызвать вызов реального метода?

Существует также вторая проблема с вышеуказанным. Когда я определяю класс mock внутри блока Expectations (как указано выше), кажется, что вместо вызывается только конструктор 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() вызывается также. Какие-нибудь идеи?

ответ

0

Наконец-то я смог написать свои тесты таким образом, что правый конструктор вызван и никакой реальной операции с базой данных не произошло. Я думаю, что часть проблемы, с которой я столкнулся, заключалась в том, что один из методов в блоке «Ожидания» получал другой объект, чем я ожидал от параметра, который меня не интересовал. И я думаю, что другая часть моей проблемы заключалась в смешивании роли класса MockUp и записи ожиданий.

Код испытания не изменился. Вот мой упрощенный пример еще раз для удобства:

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; 
    } 
} 

Вот в основном то, что я в конечном итоге в конечном итоге с для тестового кода:

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); 
} 

Ключевые моменты были, что A) Я создал класс макете, чтобы переопределить БД операции и B) создал локальный экземпляр этого частично изделенного экземпляра для записи моих ожиданий.

0

Вы не используете высмеивал объект для вызова вашей fucntion т.е. private MyObject mock; но реальный объект test,

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

Вызов testStuff() на mock вместо test.

Все экземпляры не будут автоматически высмеиваться, вы должны работать с издеваемыми экземплярами.

+0

testStuff() не имеет значения. Фактически, я удалю его из своего примера. Проблема заключается в том, что во время строительства проблема insert(). Я собираюсь изменить свой пример, надеюсь, прояснить его. Тем не менее, вы говорите: «Все экземпляры не будут автоматически высмеиваться», но в документации говорится: «Если объект класса задан [в конструкторе ожиданий] ... все экземпляры указанного класса будут рассматриваться как посмеянные экземпляры ». Можете ли вы уточнить свое заявление? – Didjit

+0

Укажите мне документацию, которую вы цитируете.Поймите, что «Ожидания» - это этап записи для вызываний на издевательствах. Это не фаза создания фальсифицированного объекта. Выделенные объекты, созданные с помощью 'new MockUp' или' Mock' и Ìnjectable' –

+0

Кроме того, его очень запутанно читать ваш код. «MyObject'definition имеет только один конструктор« MyObject (Object obj) », но в вашем тестовом коде вы делаете« новый MyObject («что-то», «что-то еще»); ​​«поэтому я не уверен, что я ищу в. Если ваши реальные методы получаются вызываемыми, то это случай, когда вы вызываете метод на реальном объекте, а не поддельный. –

Смежные вопросы