我今天才开始了解Mockito.我写了一些简单的测试(使用JUnit,见下文),但我无法弄清楚如何在Spring的托管bean中使用模拟对象.使用Spring的最佳实践是什么?我应该如何向我的bean注入模拟依赖?
你可以跳过这个直到回到我的问题.
首先,我学到了什么.这是非常好的文章Mocks Are Not Stubs解释了基础知识(Mock的检查行为验证不是状态验证).然后有一个很好的例子Mockito 和这里更容易嘲笑mockito.我们有解释说Mockito的模拟对象都是模拟和存根.
这个测试
@Test
public void testReal(){
List<String> mockedList = mock(List.class);
//stubbing
//when(mockedList.get(0)).thenReturn("first");
mockedList.get(anyInt());
OngoingStubbing<String> stub= when(null);
stub.thenReturn("first");
//String res = mockedList.get(0);
//System.out.println(res);
//you can also verify using argument matcher
//verify(mockedList).get(anyInt());
verify(mockedList);
mockedList.get(anyInt());
}
Run Code Online (Sandbox Code Playgroud)
工作得很好.
回到我的问题.在这里注入Mockito模拟到Spring bean有人试图使用Springs ReflectionTestUtils.setField()
,但是在这里Spring Integration Tests,创建模拟对象我们建议改变 Spring的上下文.
我真的不明白最后两个链接......有人可以向我解释一下Spring与Mockito有什么问题吗?这个解决方案有什么问题?
@InjectMocks
private MyTestObject testObject …
Run Code Online (Sandbox Code Playgroud) 我正在研究JDK 1.7的新功能,我无法得到它为MethodHandle设计的内容?我理解(直接)静态方法的调用(以及在这种情况下直接使用Core Reflection API).我也理解(直接)调用虚方法(非静态,非最终)(以及使用需要通过Class层次结构的Core Reflection API obj.getClass().getSuperclass()
).非虚方法的调用可以视为前者的特殊情况.
是的,我知道存在重载问题.如果要调用方法,则必须提供确切的签名.您无法以简单的方式检查重载方法.
但是,MethodHandle是什么?Reflection API允许您"查看"对象内部,而无需任何预先假设(如实现接口).您可以出于某种目的检查对象.但是MethodHandle的设计是什么呢?我应该何时何地使用它?
更新:我现在正在阅读这篇http://blog.headius.com/2008/09/first-taste-of-invokedynamic.html文章.根据它,主要目标是简化在JVM上运行的脚本语言的生命,而不是Java语言本身.
更新-2:我读完了上面的链接,从那里引用了一些引文:
JVM将成为构建动态语言的最佳VM,因为它已经是一个动态语言VM.而InvokeDynamic通过向一流的JVM公民推广动态语言,将证明这一点.
使用反射来调用方法效果很好......除了一些问题.必须从特定类型检索方法对象,并且不能以一般方式创建.<...>
...反射调用比直接调用慢很多.多年来,JVM已经非常擅长快速反映调用.现代JVM实际上在幕后生成了一堆代码,以避免处理大量开销的旧JVM.但简单的事实是,通过任意数量的层反射访问总是比直接调用慢,部分原因是完全通用的"调用"方法必须检查并重新检查接收器类型,参数类型,可见性和其他细节,但因为参数必须都是对象(所以原语是对象框),并且必须作为一个数组提供,以涵盖所有可能的arities(所以参数得到数组框).
对于执行少量反射调用的库,性能差异可能无关紧要,特别是如果这些调用主要是为了在内存中动态设置静态结构,可以进行正常调用.但是在动态语言中,每次调用必须使用这些机制,这是一个严重的性能损失.
http://blog.headius.com/2008/09/first-taste-of-invokedynamic.html
因此,对于Java程序员来说,它基本上是无用的.我对吗?从这个角度来看,它只能被视为Core Reflection API的替代方式.
假设我有实现它的接口和实现类,我想为此编写单元测试.我应该测试什么接口或Impl?
这是一个例子:
public interface HelloInterface {
public void sayHello();
}
public class HelloInterfaceImpl implements HelloInterface {
private PrintStream target = System.out;
@Override
public void sayHello() {
target.print("Hello World");
}
public void setTarget(PrintStream target){
this.target = target;
}
}
Run Code Online (Sandbox Code Playgroud)
所以,我有HelloInterface和HelloInterfaceImpl来实现它.什么是被测单元接口或Impl?
我认为它应该是HelloInterface.考虑下面的JUnit测试草图:
public class HelloInterfaceTest {
private HelloInterface hi;
@Before
public void setUp() {
hi = new HelloInterfaceImpl();
}
@Test
public void testDefaultBehaviourEndsNormally() {
hi.sayHello();
// no NullPointerException here
}
@Test
public void testCheckHelloWorld() throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream(); …
Run Code Online (Sandbox Code Playgroud) 我非常了解JDK 1.5.众所周知,除了新的API(例如AtomicInteger)之外,还有一些主要的语言变化,例如提供对泛型的支持,添加枚举,私有自动装箱和自动取消装箱等等.
我想找到一些资源具有在JDK 1.6和1.7的新功能(最好简短描述大的新功能我喜欢阅读完整的解释).至于API的变化,只有主要的变化是可以接受的,并且对新的变更进行简短的审查(例如,如果我记得写有从控制台读取字符的新方法).就功能而言,我想找到完整的列表(对象分配的这种变化,现在JVM实际上可以在堆栈上创建对象以进行优化,例如,但我不知道细节).
对于JDK 1.6 核心Java技术特性和Java™SE 6与J2SE 5.0的兼容性.对于JDK 1.7 使用Java SE 7异常更改,但它是不完整的列表.
如何通过MethodHandles.lookup()
?获取所有声明的方法?如何获取所有声明的字段?
什么是差异MethodHandle.invoke()
,MethodHandle.invokeExact()
和MethodHandle.invokeWithArguments()
此外,我将非常感谢有关使用Methodhandle API for Java devloper的教程.我强调,我正在编写静态类型语言普通旧Java,我不是JVM开发人员,特别是我对整个字节码废话(invokedynamic)并不感兴趣.我想弄清楚如何使用这个新API而不是Java Core API.
EDITED-2:
@Glen Best下面提供了一些我只想提供的参考资料http://www.oraclejavamagazine-digital.com/javamagazine/20130102?pg=52&search_term=methodhandle&doc_id=-1#pg50这正是我想要的.我发现实际上有一些新的词汇表.例如,目标实际上是指MethodHandle(而不是发送的对象),而调用站点实际上是"调用""函数指针"又称MethodHandle的代码.此外,它是一定要了解MethodHandle API是不是更换为核心映像API,而不是suplement它.例如,您无法使用MethodHandle"发现"所有方法,而您需要Core Reflection API.但是当你"找到"你想要的方法时,你可以切换到MethodHandle,例如,绑定一些参数或者将它的签名"改变"(改编)为varargs.
编辑:
我仍在努力找出答案.我写了一些我想与大家分享的测试.
package alexander.berkovich;
import static org.junit.Assert.assertSame;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import org.junit.BeforeClass;
import org.junit.Test;
public class MethodHandlerCleanTest {
public static MethodHandles.Lookup lookup;
@BeforeClass
public static void asetUp(){
lookup = MethodHandles.lookup();
}
public static class Check {
public void primitive(final int …
Run Code Online (Sandbox Code Playgroud) 好吧,我通过相关问题,我阅读了JDK 1.7的源代码,但我找不到答案.
在这个问题中,我想完全忽略fillInStackTrace
.
从JDK 1.4 initCause()
开始,添加了方法.例如,当您使用核心反射来调用该方法时,您会收到InvocationTargetException,其中包含具有目标异常的原因.
当我看到这个功能时,我也开始在这样的场景中使用它
try {
//contains some code that can throw new IOException();
}
catch(IOException e){
throw new RuntimeException(e);
}
Run Code Online (Sandbox Code Playgroud)
所以,我抓住了一个异常,我还没准备好在这里处理它并且我重新抛出新的异常,其中我有原始异常作为原因.在一些scenarious而不是RuntimeException,但我的自定义异常被使用,所以有时我也调用e.getCause()
,以便在外部块中正确处理此异常.
这是JDK 1.7之前的情况.我应该何时何地使用addSuppressed()
?我应该将上面的代码更改为
try {
//contains some code that can throw new IOException();
}
catch(IOException e){
RuntimeException re= new RuntimeException(e.getMessage());
re.addSuppressed(e);
throw re;
}
Run Code Online (Sandbox Code Playgroud)
作为奖励问题,为什么不addSuppressed()
返回Throwable
作为initCause()
确实允许throw (RuntimeException)new RuntimeException().initCause(e);
?例如,为什么我不能这样做?:
try {
//contains some code that can throw new IOException();
}
catch(IOException e){
throw …
Run Code Online (Sandbox Code Playgroud) 简而言之: 1.我有一些最后的课,我想为它创建动态代理.我该怎么做?2.我可以将MethodHandle转换为Method吗?
详细信息 首先,是否存在将MethodHandle转换为Method的API?像java.lang.invoke.MethodHandles中的东西
public MethodHandle unreflect(Method m) throws IllegalAccessException;
Run Code Online (Sandbox Code Playgroud)
但相反的方式呢?
假设我想创建动态java.lang.reflect.Method.这是违法的
public final
class Method extends AccessibleObject implements GenericDeclaration,
Member ;
Run Code Online (Sandbox Code Playgroud)
所以,如果我想使用JDK动态代理,我必须使用一些接口(例如成员).虽然有2个主要的抽屉.一,方法如
public Class<?>[] getParameterTypes();
Run Code Online (Sandbox Code Playgroud)
等
public Class<?> getReturnType();
Run Code Online (Sandbox Code Playgroud)
不是任何界面的一部分,而它们被广泛使用.
第二个缺点是它无法提供直接替换.也就是说,我无法将我的动态代理传递给期望java.lang.reflect.Method的代码.
另一种方法是使用CGLIB或Javaassist.AFAIK,CGLIB无法代理最终班级,是吗?Javaassist可以代理最终类吗?如何从班级中"删除"最终标识符?AFAIL,Javvassist可以某种方式做到......
就JavaDoc状态而言,MethodHandles.lookup()
返回能够访问与此函数的调用者相同的方法/函数/构造函数的工具.具体来说,如果调用者可以访问某些私有数据,那么这个MethodHandles.Lookup工具.下面的代码表明这是错误的.哪里弄错了?
public class MethodHandlerAccessTest {
private static class NestedClass {
private static void foo(){}
}
@Test
public void testPrivateAccess() throws Throwable {
NestedClass.foo(); //compiles and executes perfectly
MethodType type = MethodType.methodType(void.class);
MethodHandles.Lookup lookup = MethodHandles.lookup();
MethodHandle mh = lookup.findStatic(NestedClass.class, "foo", type);
}
}
Run Code Online (Sandbox Code Playgroud)
编辑:
这就是我得到的:
java.lang.IllegalAccessException:member is private:MethodHandlerAccessTest $ NestedClass.foo()void,来自java.lang.invoke.MethodHandles的java.lang.invoke.MemberName.makeAccessException(MemberName.java:507)的MethodHandlerAccessTest $ Lookup.checkAccess (MethodHandles.java:1182)java.lang上的java.lang.invoke.MethodHandles $ Lookup.checkMethod(MethodHandles.java:1162)java.lang上的$ Lookup.accessStatic(MethodHandles.java:591).在sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:)的sun.reflect.NativeMethodAccessorImpl.invoke0(本地方法)的MethodHandlerAccessTest.testPrivateAccess(MethodHandlerAccessTest.java:19)上的invoke.MethodHandles $ Lookup.findStatic(MethodHandles.java:587) 57)在sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)at java.lang.reflect.Method.invoke(Method.java:601)at org.junit.runners.model.FrameworkMethod $ 1.runReflectiveCall(FrameworkMethod. java:47)at org.junit.internal.runners.model.Re flectiveCallable.run(ReflectiveCallable.java:12)org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)在org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)在org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)在org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50 )org.junit.runners.ParentRunner $ 3.run(ParentRunner.java:238)org.junit.runners.ParentRunner $ 1.schedule(ParentRunner.java:63)at org.junit.runners.ParentRunner.runChildren(ParentRunner. java:236)org.junit.runners.ParentRunner.access $ 000(ParentRunner.java:53)org.junit.runners.ParentRunner $ 2.evaluate(ParentRunner.java:229)org.junit.runners.ParentRunner.run (ParentRunner.java:309)在org.eclipse.jdt.internal.junit.runner.TestExecution的org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50).运行(TestExecution.java:38)org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner. …
现有的内部类有什么问题,为什么内部类不能用于表示闭包?
目前,我将在这里发布一些资源入手.
首先,下面列出了什么是封闭的概述.它与语言无关.我建议阅读它关闭http://martinfowler.com/bliki/Closure.html
稍后加一点
[2007年1月]闭包的定义http://gafter.blogspot.com/2007/01/definition-of-closures.html
结束
[2011年12月] Lambda状态 http://cr.openjdk.java.net/~briangoetz/lambda/lambda-state-4.html
[2007年10月]编程语言高级主题:Java闭包http://www.youtube.com/watch?v=0zVizaCOhME
[2011年1月4日] JSR 292善良:使用invokedynamic进行Lambda到SAM类型的转换http://weblogs.java.net/blog/forax/archive/2011/01/04/jsr-292-goodness-lambda-sam-type γ变换-使用-invokedynamic
我使用的是Jenkins 1.462,maven版本是3.0.4.在Jenkins我启用了复选框"增量构建 - 仅构建已更改的模块"
我想弄清楚2个问题:
增量构建是否足够? 这里如何在Subversion的多模块Maven构建中触发单个模块的Jenkins构建?例如,它表示它不能100%工作这里声明增量构建是互补的,例如http://www.slideshare.net/andrewbayer/7-habits-of-highly-effective-jenkins-users完整版本,而不是替代品.
是否增量构建 - 仅构建已更改的模块实际上是否按预期工作? 我的意思是什么?如果我有模块A,B,X,C,D.X使用A和B,C使用X,D使用C,我在X模块中进行更改.比我想要重新编译模块X(itslef),C(直接使用X)和D(即传递闭包; D使用C,使用C).
注意:这是我为了启用增量构建而做的唯一更改.
我在Java上寻找一些例子,以便更好地理解什么是DCI以及如何使用它.
我在C++找到了一些很棒的DCI示例http://fulloo.info/Examples/C++Examples/Account1/
如果您不熟悉DCI架构,请阅读http://www.artima.com/articles/dci_vision.html,或在此处观看一些介绍http://www.tele-task.de/archive/video/flash/ 16130 /最后一个链接更多是关于OO的弱点.
奖金问题:DCI确实是下一个范式转变吗?
我正在编写显式调用 Bean Validation (JSR-303) 的代码,如下所示:
public class Example {
@DecimalMin(value = "0")
private static final String ANNOTATED = "";
public void isPossitiveNumber(String str){
ValidatorFactory factory =
Validation.buildDefaultValidatorFactory();
ConstraintValidator<DecimalMin, String>
validator =
factory.getConstraintValidatorFactory().getInstance(
DecimalMinValidatorForString.class);
validator.initialize(
ReflectionUtils.findField(getClass(), "ANNOTATED")
.getAnnotation(
DecimalMin.class));
boolean isValid = validator.isValid(str, null);
return isValid;
}
}
Run Code Online (Sandbox Code Playgroud)
请注意boolean isValid = validator.isValid(str, null); 行
我转移null
是ConstraintValidatorContext
因为我找不到获得/构建它的方法。在这种特殊情况下,这很好,因为ConstraintValidatorContext
内部没有使用,但很明显是一个黑客。我应该如何获得ConstraintValidatorContext
?
添加
我被要求提供用例。因此,例如,我正在编写自定义验证器,并且我想重用现有的验证。或者我正在编写上面描述的平面 Java 代码,我想重用现有的验证。