Jug*_*kar 11 java unit-testing mocking jmock
我希望实现以下行为.我的测试类依赖于其他一些类,我希望用jMock来模拟这种依赖.大多数方法会返回一些标准值,但有一个方法,在这里我想打个电话到存根实现,我知道我可以调用从这个方法will(...),但我想用完全相同的参数来调用的方法传递给模拟方法的.
测试
@Test
public void MyTest(){
Mockery context = new Mockery() {
{
setImposteriser(ClassImposteriser.INSTANCE);
}
};
IDependency mockObject = context.mock(IDependency.class);
Expectations exp = new Expectations() {
{
allowing(mockObject).methodToInvoke(????);
will(stubMethodToBeInvokedInstead(????));
}
};
}
Run Code Online (Sandbox Code Playgroud)
接口
public interface IDependency {
public int methodToInvoke(int arg);
}
Run Code Online (Sandbox Code Playgroud)
要改为调用的方法
public int stubMethodToBeInvokedInstead(int arg){
return arg;
}
Run Code Online (Sandbox Code Playgroud)
那么我如何捕获传递给被模拟方法的参数,所以我可以将它们传递给存根方法呢?
编辑
再举一个例子,假设我想INameSource在下面的(C#)代码中模拟依赖关系来测试类的扬声器
public class Speaker
{
private readonly string firstName;
private readonly string surname;
private INameSource nameSource ;
public Speaker(string firstName, string surname, INameSource nameSource)
{
this.firstName = firstName;
this.surname = surname;
this.nameSource = nameSource;
}
public string Introduce()
{
string name = nameSource.CreateName(firstName, surname);
return string.Format("Hi, my name is {0}", name);
}
}
public interface INameSource
{
string CreateName(string firstName, string surname);
}
Run Code Online (Sandbox Code Playgroud)
这就是如何在Rhino Mocks for C#中完成它我理解它不会像这样容易,因为Java中缺少委托
小智 21
来自Duncan的解决方案运行良好,但是甚至有一个更简单的解决方案,而无需使用自定义匹配器.只需使用传递给CustomActions调用方法的Invocation参数.在此参数中,您可以调用getParameter(long i)方法,该方法为您提供调用的值.
所以不要这样
return matcher.getLastValue();
Run Code Online (Sandbox Code Playgroud)
用这个
return (Integer) invocation.getParameter(0);
Run Code Online (Sandbox Code Playgroud)
现在你不再需要StoringMatcher了:Duncans示例现在看起来像这样
@RunWith(JMock.class)
public class Example {
private Mockery context = new JUnit4Mockery();
@Test
public void Test() {
final IDependency mockObject = context.mock(IDependency.class);
context.checking(new Expectations() {
{
// No custom matcher required here
allowing(mockObject).methodToInvoke(with(any(Integer.class)));
// The action will return the first argument of the method invocation.
will(new CustomAction("returns first arg") {
@Override
public Object invoke(Invocation invocation) throws Throwable {
return (Integer) invocation.getParameter(0);
}
});
}
});
Integer test1 = 1;
Integer test2 = 1;
// Confirm the object passed to the mocked method is returned
Assert.assertEquals((Object) test1, mockObject.methodToInvoke(test1));
Assert.assertEquals((Object) test2, mockObject.methodToInvoke(test2));
}
public interface IDependency {
public int methodToInvoke(int arg);
}
Run Code Online (Sandbox Code Playgroud)