我正在学习TDD,但很难接受它,因为它不是直截了当的.
我无法回答的问题是" 如何在任何实现代码存在之前编写测试? ".
如果我们的目标类/目标方法/目标参数类型/目标返回类型不存在,
每个人都说出为什么,但不是如何
我已经尽力找到资源,详细说明在生产代码之前编写测试但是,假设我错过了良好的资源,他们中的大多数都充满了陈词滥调,解释了为什么TTD比专注于采用它的实践更重要.
一个用例示例.
我们假设我们正在为大学开发软件,我们的用例是课程注册.
为了简单起见,让我们将这个讨论限制在内
伪代码
ENROLL(studentId, courseId)
//check if student enrolled in less than 3 courses in the same semester as given courseId belongs in.
//if yes, enroll him/her.
//if not, return an error.
Run Code Online (Sandbox Code Playgroud)
上面的实际实现可能涉及几个涉及服务,daos等的类.
请问您能解释一下如何逐步测试 - 开发它吗?如果您使用TDD实现这一点,您是如何逐步完成的.
我希望这可以帮助像我这样的许多挣扎.
我已经声明了两个相同类类型的bean.初始化它们@Lazy.@Autowiring它们中的一个bean也自动初始化了另一个bean.我很惊讶地看到这种行为.只是好奇了解更多有关机制的信息.
码
//bean
public class HelloWorld {
public HelloWorld(String msg){
System.out.println( msg + ", " + this);
}
}
@Configuration
@Lazy
public class SpringAppContext {
@Bean(name="helloworld1")
public HelloWorld helloworld1(){
return new HelloWorld("helloworld1");
}
@Bean(name="helloworld2")
public HelloWorld helloworld2(){
return new HelloWorld("helloworld2");
}
}
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes={SpringAppContext.class})
public class SpringBeanLazyLoadTest {
@Autowired
private HelloWorld helloworld2;
@Test // this test is lame but just trying out.
public void print(){
System.out.println("Autowired: " + helloworld2);
}
}
Run Code Online (Sandbox Code Playgroud)
产量
helloworld2, my.entp.spring.HelloWorld@3a9bba
helloworld1, my.entp.spring.HelloWorld@163f7a1 …Run Code Online (Sandbox Code Playgroud) 我正在学习Builder模式
在上面的链接(Java示例)中,我注意到Builder提供了构造多个组件的接口.除了调用它们之外,我们还调用了getProduct().
我不明白的一点是,为什么Director需要逐个调用所有这些组件构造方法并最终获得结果.
/** "Director" */
class Waiter {
private PizzaBuilder pizzaBuilder;
public void setPizzaBuilder(PizzaBuilder pb) { pizzaBuilder = pb; }
public Pizza getPizza() { return pizzaBuilder.getPizza(); }
public void constructPizza() {
pizzaBuilder.createNewPizzaProduct();
pizzaBuilder.buildDough(); // construct component 1
pizzaBuilder.buildSauce(); // construct component 2
pizzaBuilder.buildTopping(); // construct component 3
}
Run Code Online (Sandbox Code Playgroud)
}
为什么我们不在ConcreteBuilder类中包含构造组件1,2,3的代码,而不是在Director中,实际上消除了Director层.
我知道上述方法可能会将Builder模式转变为其他方式,但我不明白为什么Director会逐步完成工作.有什么好处?如果有多个导演,会有重复的代码,对吧?我可能不理解执行Builder模式背后的动机......
更新:Builder模式是否专注于在创建更大的复杂对象时提供可自定义组件选择?否则,截至目前,我没有看到引入额外层的重点,即主任.
即使是这种情况,Decorator模式也可能是通过动态定制组件来实现相同目标.在某处,我错过了Builder背后的那一点...... :(
根据我的理解,真正的 BDD 更多的是满足业务规范,但我认为从类级别的行为开始可能是值得的,因为我正在努力采用 TDD,而 BDD 命名使它更容易。
让我们关注 BDD 风格的单元测试(在类级别)。
我开始以反映预期行为的方式命名我的测试类,使用本文中建议的“When” 。它真的很有效。然而很快,我意识到这样的测试类名称可能会产生以下维护后果。
为手头的课程找到测试课程并不容易。
我习惯了传统的命名“ClassnameTest”,在这种情况下,我可以快速找到测试类。
我使用Java 和 JUnit4,但不幸的是我没有像给定的内置语言结构等。
让我们考虑以下示例。
public class Lion{...}
Run Code Online (Sandbox Code Playgroud)
测试类
public class WhenLionIsHungy{
@Test public void should_eat_meat(){...}
@Test public void should_not_eat_grass(){...}
@Test ...
}
public class WhenLionHunts{...}
public class WhenLionIsWithCubs{...}
...
Run Code Online (Sandbox Code Playgroud)
请原谅我举个例子。假设它们都是有效的测试类。除非您确定我们永远不应该为目标类设置多个基于行为的测试类,否则不要担心它。
BDD 是将测试转换为文档的优雅解决方案,上面的示例反映了这一点。毕竟,测试像“testMoneyTransfer()”这样的方法永远不会提供任何见解。
上面是一个快乐的例子,但猜测名为“LibraryServiceImpl”的类的测试类将是一场噩梦。
是 WhenBookIsRequested 或 WhenLibraryIsClosed 还是两者兼而有之?
单元测试应该作为完整或某种程度的文档。然而,在 LibraryServiceImpl 案例中,文档本身并不容易被发现。
即使您正确命名了一个类并使用 SRP 对其进行设计,仍然很难找到测试类,因为搜索引用也可能会在测试文件夹中返回 100 次点击。
我第一次尝试使用@Suite 解决问题。
@RunWith(Suite.class)
@Suite.SuiteClasses({WhenLionIsHungy.class,
WhenLionHunts.class,
WhenLionIsWithCubs.class
})
public class LionTest{}
Run Code Online (Sandbox Code Playgroud)
它解决什么问题?
它介绍了什么?
我第二次尝试使用内部类解决问题。 参考 …
我正在尝试在开发环境中提高Java Web应用程序的启动性能.它使用jetty-maven-plugin并mvn jetty:run用于启动应用程序.
我按照http://www.eclipse.org/jetty/documentation/9.3.x/jetty-classloading.html上的说明注册了这个新的CachingWebAppClassLoader.
<Configure id="mywebapp" class="org.eclipse.jetty.webapp.WebAppContext">
...
<Set name="classLoader">
<New class="org.eclipse.jetty.webapp.CachingWebAppClassLoader">
<Arg><Ref refid="mywebapp"/></Arg>
</New>
</Set>
...
</Configure>
Run Code Online (Sandbox Code Playgroud)
然而,org.eclipse.jetty.webapp.WebAppClassLoader.*继续出现在jvisualvm CPU采样器但不是CachingWebAppClassLoader
我验证了我的类加载器注册至少是通过提供一个无效的类名来发现的ClassNotFoundException.我猜我的类加载器的配置正在消耗但没有被使用或类似的东西.有任何想法吗?
此外,如果您了解可用于提高性能的任何其他类加载器变体,请告诉我.
我最近发现了几篇文章,可以通过将 JDK 放在 ramdisk 上并让它用于构建目的来提高 IDE(比如 eclipse)性能。我可以猜测这如何使事情更快,但我不知道确切的细节。
IDE 不会将所需的 JDK 部分加载到内存中吗?将 JDK 保留在 ramdisk 上是一次性的好处还是连续的事情。如果有人可以阐明确切的机制,那就太好了。
动机是我正在处理的项目很大,有时我确实需要在 Eclipse 中打开“自动构建”功能。我正在探索加快构建过程的方法
笔记
我发布了一个不同的问题,用术语“JVM”代替“JDK”,这使它变得混乱和误导。我为此道歉,并重新组织了我的问题。
是否有任何设置可以配置以使 jvisualvm 以人类可读的格式显示内存和其他数字,即以 MB 为单位而不是以字节为单位等。
我确实进行了调查,但没有找到任何结果。
我是 Spring Boot 的新手,正在阅读有关 @ConfigurationProperties 注释如何在没有 @Value 注释的情况下自动注入字段值的信息。
@Configuration
@ConfigurationProperties(locations = "classpath:some.properties", prefix = "something")
public class MyConfiguration { .. }
Run Code Online (Sandbox Code Playgroud)
我想使用 GroovyConfigSlurper来读取我的属性配置。有没有办法@ConfigurationProperties与自定义属性阅读器相关联,可能是 Spring 类的自定义扩展处理ConfigSlurper?或者有没有办法用不同的功能模拟相同的行为?
在运行进程时,WSL中的滚动条不可用。我向上滚动的尝试是徒劳的,因为由于正在运行某个进程,系统会自动将滚动条设置到窗口的底部。
就我而言,我调用./gradlew bootRun,它在8080上启动一个应用程序并保留打印日志。我试图通过向上滚动来读取日志,但是滚动条的任何手动向上移动都被覆盖。
只是想知道是否是其他Windows 10设置导致了此问题,或者是bash专用还是gradle专用?如何解决?
一般来说,最好避免 Spring Cloud Gateway 中的任何阻塞计算。
但是,可能存在一些[阻塞非 IO] 昂贵的操作,例如某些有效负载的加密/解密等。
根据迄今为止的调查,我从实时 Spring Cloud Gateway 应用程序中发现了 2 个线程池。
问)在有界弹性线程池与事件循环线程池中执行昂贵的 CPU 计算的成本是多少。根据我的理解,我们绝对应该避免事件循环线程池上的任何阻塞代码。
看起来默认情况下所有过滤器都在事件循环线程池上运行。所以卸载到boundedElastic实际上会带来线程切换的成本。
java ×5
junit ×2
spring ×2
tdd ×2
unit-testing ×2
bdd ×1
eclipse ×1
gradle ×1
gradlew ×1
jetty ×1
jvisualvm ×1
maven ×1
ooad ×1
oop ×1
ramdisk ×1
spring-bean ×1
spring-boot ×1
visualvm ×1
windows-10 ×1