Junit 使用动态参数模拟方法调用

Junit 使用动态参数模拟方法调用,junit,junit4,easymock,powermock,Junit,Junit4,Easymock,Powermock,我有一个方法如下 private void validate(String schemaName){ .... SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);**strong text** Source schemaFile = new SteamSource(getClass().getClassLoader().getResourceAsStr

我有一个方法如下

private void validate(String schemaName){
    ....
    SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);**strong text**
    Source schemaFile = new SteamSource(getClass().getClassLoader().getResourceAsStream(schemaName));
    Schema schema = factory.newSchema(schemaFile);
    ....
}
这个方法是从我需要测试的另一个方法(使用easymock和powermock)调用的。我在努力模仿下面这句话

Source schemaFile = new SteamSource(getClass().getClassLoader().getResourceAsStream(schemaName));
有人能给我一些线索吗

现状

下面是模拟语句

expectNew(StreamSource.class, anyObject(InputStream.class)).andReturn(mockedobject); 

Powermock.replay(mockedobject, StreamSrouce.class); 
这将引发以下异常

org.powermock.reflect.exceptions.TooManyConstructorsFoundException: Several matching constructors found, please specify the argument parameter types so that PowerMock can determine which method you're referring to. 
Matching constructors in class javax.xml.transform.stream.StreamSource were:

我认为您可以使用
powermock
以以下方式完成它(我只是按照教程进行操作):

假设你的班级是这样的:

public class MyClass {
   private void validate(String schemaName) {
   ....
   SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);**strong text**
   Source schemaFile = new SteamSource(getClass().getClassLoader().getResourceAsStream(schemaName));
   Schema schema = factory.newSchema(schemaFile);
....
   }
}
@RunWith(PowerMockRunner.class) 
@PrepareForTest(MyClass.class) 
public class MyClassTest {

   private MyClass testedClass = new MyClass();
   private ClassLoader mockedClassLoader = createMock(ClassLoader.class);
   private InputStream mockedInputStream = createMock(InputStream.class);

   @Before
   public void setUp() {
       PowerMock.createPartialMock(MyClass.class, "getClass");
       expect(testedClass.getClass()).andReturn(mockedClassLoader);
       expected(mockedClassLoader.getResourceAsStream(***You string***)).andReturn(mockedInputStream);
       replayAll(); // Not sure if that's the name of the method - you need to call replay on all mocks
   }


   @Test
   public void testValidate() {
       // Run your test logic here
   }
}
您应该创建一个如下所示的测试类:

public class MyClass {
   private void validate(String schemaName) {
   ....
   SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);**strong text**
   Source schemaFile = new SteamSource(getClass().getClassLoader().getResourceAsStream(schemaName));
   Schema schema = factory.newSchema(schemaFile);
....
   }
}
@RunWith(PowerMockRunner.class) 
@PrepareForTest(MyClass.class) 
public class MyClassTest {

   private MyClass testedClass = new MyClass();
   private ClassLoader mockedClassLoader = createMock(ClassLoader.class);
   private InputStream mockedInputStream = createMock(InputStream.class);

   @Before
   public void setUp() {
       PowerMock.createPartialMock(MyClass.class, "getClass");
       expect(testedClass.getClass()).andReturn(mockedClassLoader);
       expected(mockedClassLoader.getResourceAsStream(***You string***)).andReturn(mockedInputStream);
       replayAll(); // Not sure if that's the name of the method - you need to call replay on all mocks
   }


   @Test
   public void testValidate() {
       // Run your test logic here
   }
}

如果我使用的一些
easymock
方法的名称有点不同,请原谅。但这是基本想法。

我认为您需要以下一种或几种方法的组合。使用
Powermock
构造函数对
新StreamSource
进行模拟,如文档所示。您可能还需要为
SchemaFactory
使用mock,这意味着您需要通过模拟静态工厂方法调用,我也面临同样的问题。请引导我。@K.Senthuran-我添加了一个答案。真的希望这就是你想要的。除了我最初的问题,有人建议使用构造函数mock,这也是一种可能性。你可以看看我关于如何做到这一点的另一个问题的答案:这似乎太过分了。模拟构造函数调用。我尝试了这个Avi,做了一些修改。我必须使用类似于“EasyMock.expect(..)”的expect调用,然后我必须更改的设置方法的第二行类似于“EasyMock.expect(testedClass.getClass().getClassLoader()).andReturn(mockedClassLoader);”。第三线我想你又期待了。但是我从安装方法的第2行得到了“java.lang.IllegalStateException:no last call on a mock available”异常。@susithasenarath您是否将
PrepareForTest
注释放在模拟类的顶部了?它是important@Avi你能解释一下setUp方法里面的行吗?@susithasenarath-这个想法是只模拟类的一部分(因为你想测试的大多数类)。第一行定义要模拟的方法,第二行定义调用
getClass()
时发生的情况,即-返回模拟的类装入器,而不是原始类装入器。然后在模拟类加载器上执行相同的操作,并返回模拟的
InputStream
。重播会记录这些动作。不,您可以运行测试并模拟所需的行;由于“getClass().getClassLoader().getResourceAsStream(schemaName)”返回一个InputStream,我将参数作为InputStream类放置。这对吗?不行。只是replayAll()应该启动模拟,不是吗。我有easymock和Powermock语句。首先要做的是选择一个。同时使用两者会使你的生活变得更加复杂。Powermock包含easymock不是吗?不知道你在问什么。Powermock可以执行Easymock可以执行的所有相同类型的模拟,因此没有理由同时使用这两种类型。