Как написать UT для макета внутреннего объекта в одном методе? - PullRequest
13 голосов
/ 16 сентября 2011

Например, у меня есть класс Java, как показано ниже. Я собираюсь написать модульный тест для doWork (), поэтому я хотел бы контролировать поведение obj. Но очевидно, что объект obj создается внутренне.

Как я могу написать это UT? Сейчас я использую Junit + Mockito.

class ToBeTest{
    public ToBeTest(){}
    public boolean doWork(){
        OtherObject obj=new OtherObject();
        return obj.work();
    }
}

Спасибо заранее. :)

Кстати, реальность такова, что я пишу UT для класса другого человека. Поэтому я не хочу это менять. Он был полностью протестирован интегральным тестом.

Ответы [ 6 ]

10 голосов
/ 16 сентября 2011

Если вы не можете изменить код, вы можете использовать Powermock вместе с junit и Mockito, чтобы высмеивать строительство новых объектов.

@Test
public void testDoWork() throws Exception{

    MyTest mytest = new MyTest();

    OtherObj obj = new OtherObj();
    obj.test="mocked Test"; //here you can add any other needed values to obj

    PowerMockito.whenNew(OtherObj.class).withNoArguments().thenReturn(obj);

    String result = mytest.doWork();
    Assert.assertTrue(result.equalsIgnoreCase("mocked Test"));
}
2 голосов
/ 16 сентября 2011

Лучший способ - написать код для поддержки тестирования ( Разработка через тестирование подчеркивает это). На данный момент ваш код написан так, что его сложно тестировать.

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

1 голос
/ 16 сентября 2011

Это очень просто:

import org.junit.*;
import mockit.*;

@Test
public void justMockIt()
{
    new NonStrictExpectations() { OtherObject o; { o.work(); result = true; }};

    assert new ToBeTest().doWork();
}

... при использовании JMockit .

1 голос
/ 16 сентября 2011

Это классический пример, где вы должны использовать внедрение зависимостей .

Короче говоря, вместо создания объекта (зависимости) внутри, вы передаете его в конструктор или используете фабрику для создания того, что вы хотите (фабрика возвращает реальную реализацию в производственном коде и другую в тесте). Это дает вам возможность изменить реализацию при тестировании.

Посмотрите на приведенные ниже примеры, как я указал, или Google для " Пример внедрения зависимости Java ".

1 голос
/ 16 сентября 2011

Вы не можете легко.Я могу придумать два способа сделать это, и ни один из них не поддерживается Mockito или jUnit из коробки, насколько мне известно:

1) Манипулирование байтовым кодом с использованием cglib или подобной библиотеки, которая будет умереннотрудно сделать и, вероятно, довольно хрупкий.

2) Альтернативный загрузчик классов.Вы можете создать загрузчик классов, который ищет попытку загрузить класс OtherObject и заменяет его анонимным классом OtherObject, который дает вам насмешливое поведение, которое вы ищете.

Большую часть времени вы должны лечить егокак зависимость, хотя.Если вы хотите проверить открытие файла, вы, вероятно, на самом деле хотите протестировать файл, так что использование конкретного класса, вероятно, хорошо.Если вы хотите проверить поведение метода, в котором открытие файла является частью его логики, вы можете легко переместить это в зависимость, а затем смоделировать его.Фактически, это обычно имеет смысл, потому что то, что вы храните в файле один день, может потребоваться сохранить в базе данных другого или вытащить из облака на третий день, так что логика вокруг того, что вы делаете с файлом изфактический процесс открытия извлечения содержимого в любом случае часто является логическим разделением интересов.

0 голосов
/ 16 сентября 2011

Вы написали свой код, и теперь вы хотите протестировать его. Это основная причина ваших трудностей. Я предлагаю другой подход.

  1. Выразите, что метод doWork() должен делать с точки зрения поведения, которое можно наблюдать от только до public и protected (метод получения) класса ToBeTest или public и protected методы любых объектов, связанных с ToBeTest объектами. Посмотрите на Javadoc, поставляемый с библиотекой Java: он описывает, что все эти классы делают без с указанием тел методов. Когда ваш метод возвращает true? Когда возвращается false? Какие у него побочные эффекты? Вы можете найти, что вам нужно добавить несколько методов получения, чтобы сделать это. Вы можете выразить это в Javadoc для своего собственного кода .
  2. Используйте требуемое поведение, чтобы решить, какие утверждения вы можете поместить в свои юнит-тесты.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...