在理解使用Spring时,应该使用Spring配置xml实例化生产对象,并在测试时直接实例化对象是正确的吗?
例如。
MyMain.java
package org.world.hello;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MyMain {
private Room room;
public static void speak(String str)
{
System.out.println(str);
}
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
Room room = (Room) context.getBean("myRoom");
speak(room.generatePoem());
}
}
Room.java
package org.world.hello;
public class Room {
private BottleCounter bottleCounter;
private int numBottles;
public String generatePoem()
{
String str = "";
for (int i = numBottles; i>=0; i--)
{
str = str + bottleCounter.countBottle(i) + "\n";
}
return str;
}
public BottleCounter getBottleCounter() {
return bottleCounter;
}
public void setBottleCounter(BottleCounter bottleCounter) {
this.bottleCounter = bottleCounter;
}
public int getNumBottles() {
return numBottles;
}
public void setNumBottles(int numBottles) {
this.numBottles = numBottles;
}
}
BottleCounter.java
package org.world.hello;
public class BottleCounter {
public String countBottle(int i)
{
return i + " bottles of beer on the wall" + i + " bottles of beer!";
}
}
Beans.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="myRoom" class="org.world.hello.Room">
<property name="bottleCounter">
<bean id = "myBottleCounter" class = "org.world.hello.BottleCounter"/>
</property>
<property name = "numBottles" value = "10"></property>
</bean>
</beans>
输出:(我对丢失的空格表示歉意)
10 bottles of beer on the wall10 bottles of beer!
9 bottles of beer on the wall9 bottles of beer!
8 bottles of beer on the wall8 bottles of beer!
7 bottles of beer on the wall7 bottles of beer!
6 bottles of beer on the wall6 bottles of beer!
5 bottles of beer on the wall5 bottles of beer!
4 bottles of beer on the wall4 bottles of beer!
3 bottles of beer on the wall3 bottles of beer!
2 bottles of beer on the wall2 bottles of beer!
1 bottles of beer on the wall1 bottles of beer!
0 bottles of beer on the wall0 bottles of beer!
现在进行测试:
BottleCounterTest.java:
package org.world.hello;
import static org.junit.Assert.*;
import org.junit.Test;
public class BottleCounterTest {
@Test
public void testOneBottle() {
BottleCounter b = new BottleCounter();
assertEquals("1 bottles of beer on the wall1 bottles of beer!", b.countBottle(1));
}
}
非常简单。
RoomTest.java:
package org.world.hello;
import static org.junit.Assert.*;
import org.mockito.Mockito;
import org.junit.Test;
public class RoomTest {
@Test
public void testThreeBottlesAreSeperatedByNewLines()
{
Room r = new Room();
BottleCounter b = Mockito.mock(BottleCounter.class);
Mockito.when(b.countBottle(Mockito.anyInt())).thenReturn("a");
r.setBottleCounter(b);
r.setNumBottles(3);
assertEquals("a\na\na\na\n", r.generatePoem());
}
}
以这种方式实例化测试对象是否正确?
内部静态类配置:在测试Spring组件时,我们通常使用@RunWith(SpringJUnit4ClassRunner.class)
并制作我们的类@ContextConfiguration
。通过创建类,@ContextConfiguration
您可以创建用于配置的内部静态类,并且可以在其中完全控制。在这里,您将所有需要的内容定义为bean,@Autowired
并在测试中将其定义,以及取决于测试用例的依赖关系(可以是模拟对象或常规对象)。
组件扫描生产代码:如果需要测试的组件更多,则可以添加,@ComponentScan
但是我们尝试使其仅扫描所需的程序包(这是在使用@Component
批注时,但可以在其中添加XML @ContextConfiguration
)。当您不需要模拟并且您具有需要像生产环境一样的复杂设置时,这是一个不错的选择。这对于集成测试非常有用,在集成测试中,您要测试要测试的功能片中组件之间的交互方式。
混合方法:这是通常的情况,当您有许多需要生产的bean,但需要模拟一个或两个。然后,您可以@ComponentScan
生产代码,但是添加一个内部静态类,该类是,@Configuration
并且在那里定义带有注释的@Primary
Bean,以便在测试时覆盖该Bean的生产代码配置。这样做很好,因为您不需要@Configuration
使用所有已定义的bean进行长时间写入,就可以扫描所需的内容并覆盖应模拟的内容。
在您的情况下,我将采用这样的第一种方法:
package org.world.hello;
import static org.junit.Assert.*;
import org.mockito.Mockito;
import org.junit.Test;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class RoomTest {
@Configuration
//@ImportResource(value = {"path/to/resource.xml"}) if you need to load additional xml configuration
static class TestConfig {
@Bean
public BottleCounter bottleCounter() {
return Mockito.mock(BottleCounter.class);
}
@Bean
public Room room(BottleCounter bottleCounter) {
Room room = new Room();
room.setBottleCounter(bottleCounter);
//r.setNumBottles(3); if you need 3 in each test
return room;
}
}
@Autowired
private Room room; //room defined in configuration with mocked bottlecounter
@Test
public void testThreeBottlesAreSeperatedByNewLines()
{
Mockito.when(b.countBottle(Mockito.anyInt())).thenReturn("a");
r.setNumBottles(3);
assertEquals("a\na\na\na\n", r.generatePoem());
}
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句