如何在工厂类

时间:2018-05-07 20:39:24

标签: unit-testing static mockito junit4 powermock

我需要在非静态工厂类中模拟静态方法的行为。该类的实现是:

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类,以便我可以在测试时将自己的context / profile对象作为返回类型发送。我尝试了很多方法但似乎没有什么工作在这里。这是我在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: when()需要一个参数,该参数必须是模拟'上的方法调用。 例如:     当(mock.getArticles())thenReturn(文章);

此外,此错误可能会显示,因为: 1.你存在以下任何一个:final / private / equals()/ hashCode()方法。    这些方法无法进行存根/验证。 2.在()内部,你不会在模拟上调用方法,而是在其他对象上调用方法。

尝试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: when()需要一个参数,该参数必须是模拟'上的方法调用。 例如:     当(mock.getArticles())thenReturn(文章);

此外,此错误可能会显示,因为: 1.你存在以下任何一个:final / private / equals()/ hashCode()方法。    这些方法无法进行存根/验证。 2.在()内部,你不会在模拟上调用方法,而是在某些其他对象上调用方法。     在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: when()需要一个参数,该参数必须是模拟'上的方法调用。 例如:     当(mock.getArticles())thenReturn(文章);

此外,此错误可能会显示,因为: 1.你存在以下任何一个:final / private / equals()/ hashCode()方法。    这些方法无法进行存根/验证。 2.在()内部,你不会在模拟上调用方法,而是在某些其他对象上调用方法。     在org.powermock.api.mockito.PowerMockito.when(PowerMockito.java:490)

我在这里缺少什么。我已经尝试了其他几种方法,但ABCFactory.getFactory()总是返回一个新对象,但不是我的模拟对象。如何在没有更改其实现的情况下模拟ABCFactory类的行为?!请帮忙。

1 个答案:

答案 0 :(得分:1)

您是否使用了以下注释。

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