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可以执行的所有相同类型的模拟,因此没有理由同时使用这两种类型。