Как макетировать статический метод внутри фабричного класса - PullRequest
0 голосов
/ 07 мая 2018

Мне нужно посмеяться над поведением статического метода внутри нестатического фабричного класса. Реализация класса:

ABCFactory.java

public class ABCFactory extends BaseUserFactory
{
    private static final ABCFactory factory = new ABCFactory();

    public static final ABCFactory getFactory()
    {
        return factory;
    }

    public Context getContext(String authority)
    {
        return (Context)createInstance(authority);
    }

    private ABCFactory()
    {
    }

    protected Class getInterface()
    {
        return ABCFactory.class;
    }
}

Теперь этот класс используется в моем коде для получения профиля, похожего на:


Document.java:

Profile profile = ABCFactory.getFactory().getContext(authority).currentProfile();

Мне нужно смоделировать класс ABCFactory, чтобы я мог отправлять свой собственный объект контекста / профиля в качестве возвращаемого типа во время тестирования. Я перепробовал несколько методов, но здесь ничего не работает. Вот то, что я попробовал в своем тестовом классе junit.


Попробуйте 1: DocumentTest.java

ABCFactory mockABCFactory = Mockito.mock(ABCFactory.class);
ServiceProviderRegistrar.getRegistrar().bind(ABCFactory.class).toMockInstance(mockABCFactory);
Mockito.when(mockABCFactory .getFactory()).thenReturn(null);
Mockito.when(mockABCFactory .getContext(domain)).thenReturn(null);

Ошибка: org.mockito.exceptions.misusing.MissingMethodInvocationException: Когда () требуется аргумент, который должен быть «вызовом метода для макета». Например: когда (mock.getArticles ()) thenReturn (статьи);.

Кроме того, эта ошибка может отображаться, потому что: 1. Вы заглушаете любой из методов: final / private / equals () / hashCode (). Эти методы не могут быть проверены / проверены. 2. внутри when () вы вызываете не метод на макете, а на каком-то другом объекте.


Попробуйте 2: (Использование PowerMock, чтобы избежать нового вызова. DocumentTest.java

ABCFactory mockABCFactory = Mockito.mock(ABCFactory.class);
ServiceProviderRegistrar.getRegistrar().bind(ABCFactory.class).toMockInstance(mockABCFactory);
  try
  {
    PowerMockito.whenNew(ABCFactory.class).withNoArguments().thenReturn(mockABCFactory);
    PowerMockito.when(ABCFactory.getFactory()).thenReturn(mockABCFactory);
  }
  catch (Exception e)
  {
     e.printStackTrace();
  }
Mockito.when(mockABCFactory.getContext(domain)).thenReturn(null);

Ошибка: org.mockito.exceptions.misusing.MissingMethodInvocationException: Когда () требуется аргумент, который должен быть «вызовом метода для макета». Например: когда (mock.getArticles ()) thenReturn (статьи);.

Кроме того, эта ошибка может отображаться, потому что: 1. Вы заглушаете любой из методов: final / private / equals () / hashCode (). Эти методы не могут быть проверены / проверены. 2. внутри when () вы вызываете не метод на макете, а на каком-то другом объекте. в org.powermock.api.mockito.PowerMockito.when (PowerMockito.java:490)


Попробуйте 3: (используется PowerMock.mockStatic) DocumentTest.java

ABCFactory mockABCFactory= Mockito.mock(ABCFactory.class);
  ServiceProviderRegistrar.getRegistrar().bind(ABCFactory.class).toMockInstance(mockABCFactory);
 try
  {
    PowerMockito.whenNew(ABCFactory.class).withNoArguments().thenReturn(mockABCFactory);
    PowerMockito.mockStatic(ABCFactory.class);
    PowerMockito.when(ABCFactory.getFactory()).thenReturn(mockABCFactory);

  }
  catch (Exception e)
  {
     e.printStackTrace();
  }
  Mockito.when(mockABCFactory.getContext(domain)).thenReturn(null);

Ошибка: org.mockito.exceptions.misusing.MissingMethodInvocationException: Когда () требуется аргумент, который должен быть «вызовом метода для макета». Например: когда (mock.getArticles ()) thenReturn (статьи);.

Кроме того, эта ошибка может появляться, потому что: 1. Вы заглушаете любой из методов: final / private / equals () / hashCode (). Эти методы не могут быть проверены / проверены. 2. внутри when () вы вызываете не метод на макете, а на каком-то другом объекте. в org.powermock.api.mockito.PowerMockito.when (PowerMockito.java:490)


Что мне здесь не хватает. Я пробовал несколько других способов, но ABCFactory.getFactory () всегда возвращает новый объект, но не мой смоделированный объект. Как мне посмеяться над поведением класса ABCFactory без изменения его реализации ?! Пожалуйста, помогите.

1 Ответ

0 голосов
/ 08 мая 2018

Использовали ли вы следующие аннотации.

@RunWith(PowerMockRunner.class)
@PrepareForTest( ABCFactory.class )

Я пытался, и следующий код работает.

DocumentTest.class

@RunWith(PowerMockRunner.class)
@PrepareForTest( ABCFactory.class )
public class DocumentTest
{
  /** Unit under test. */
  private Document user;

  @Before public void setUp() {
     user = new Document();
     ABCFactory abc = ABCFactory.getFactory();
     PowerMockito.mockStatic(ABCFactory.class);
     PowerMockito.when(ABCFactory.getFactory()).thenReturn(abc);    
  }  

  @Test public void testABC() {
     assertEquals("", user.useFactory() );
  }
}

Класс документа

public class Document
{
 public String useFactory(){
   String profile = ABCFactory.getFactory().getContext("");
   return profile;
 }
}
...