Unit testing 如何在工厂类中模拟静态方法

Unit testing 如何在工厂类中模拟静态方法,unit-testing,static,mockito,junit4,powermock,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; } pu

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

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;
    }
}
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);
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);
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);
现在,在我的代码中使用这个类来获取概要文件,如下所示:


Document.java:

Profile profile = ABCFactory.getFactory().getContext(authority).currentProfile();
我需要模拟ABCFactory类,以便在测试时可以将自己的上下文/概要文件对象作为返回类型发送。我尝试了很多方法,但在这里似乎什么都不起作用。下面是我在junit测试类中尝试的内容


尝试1: DocumentTest.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;
    }
}
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);
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);
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()需要的参数必须是“模拟的方法调用”。 例如: when(mock.getArticles())。然后返回(articles)

此外,出现此错误的原因可能是: 1.您可以存根:final/private/equals()/hashCode()方法。 这些方法无法存根/验证。 2.在when()中,您不在mock上调用方法,而是在其他对象上调用方法


尝试2:(使用PowerMock来避免新的调用。 DocumentTest.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;
    }
}
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);
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);
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()需要的参数必须是“模拟的方法调用”。 例如: when(mock.getArticles())。然后返回(articles)

此外,出现此错误的原因可能是: 1.可以存根:final/private/equals()/hashCode()方法中的任意一个。 这些方法无法存根/验证。 2.在when()中,您不在mock上调用方法,而是在其他对象上调用方法。 位于org.powermock.api.mockito.PowerMockito.when(PowerMockito.java:490)


尝试3:(使用PowerMock.mockStatic) DocumentTest.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;
    }
}
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);
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);
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()需要的参数必须是“模拟的方法调用”。 例如: when(mock.getArticles())。然后返回(articles)

此外,出现此错误的原因可能是: 1.可以存根:final/private/equals()/hashCode()方法中的任意一个。 这些方法无法存根/验证。 2.在when()中,您不在mock上调用方法,而是在其他对象上调用方法。 位于org.powermock.api.mockito.PowerMockito.when(PowerMockito.java:490)



我在这里遗漏了什么。我尝试了其他几种方法,但是ABCFactory.getFactory()总是返回一个新对象,而不是我的模拟对象。如何在不改变其实现的情况下模拟ABCFactory类的行为呢?!请帮助。

是否使用了以下注释

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