【发布时间】:2014-04-24 18:16:54
【问题描述】:
我正在尝试掌握 EasyMock,以便在 spring-ws Web 服务上运行一些服务器端集成测试。我有一个 DAO,我想模拟我的集成测试,我已经成功地自动装配它,但我不知道如何在自动装配后设置期望。
我的 spring 上下文 xml 中有以下内容:
<bean id="accountServiceDao" class="org.easymock.EasyMock" factory-method="createMock">
<constructor-arg value="com.xxx.account.dao.AccountServiceDao" />
</bean>
<bean id="notMockedDao" class="com.xxx.account.dao.AccountServiceDaoImpl"/>
<context:component-scan base-package="com.xxx.account" />
<context:property-placeholder location="classpath:accountDetailService_test.properties" />
<sws:annotation-driven />
<jdbc:embedded-database id="dataSource" type="HSQL">
<jdbc:script location="classpath:sql/db_schema.sql" />
<jdbc:script location="classpath:sql/test_data.sql" />
</jdbc:embedded-database>
我的虚拟测试如下:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "file:src/main/webapp/WEB-INF/applicationContext_test.xml" })
public class AccountDetailServiceMockIntergrationTest {
@Autowired
private ApplicationContext applicationContext;
private MockWebServiceClient mockClient;
@Before
public void createClient() {
mockClient = MockWebServiceClient.createClient(applicationContext);
/* Set the expectations for the autowired mock dao here */
}
@Test
public void customerEndpoint() throws Exception {
Source requestPayload = new StringSource(TestData.requestXML);
Source responsePayload = new StringSource(TestData.responseXML);
mockClient.sendRequest(withPayload(requestPayload)).andExpect(
payload(responsePayload));
}
}
命中的端点如下:
@Autowired
private AccountService accountService;
@PayloadRoot(localPart = "AccountSearchRequest", namespace = TARGET_NAMESPACE)
public @ResponsePayload
AccountSearchResponse getAccountDetails(
@RequestPayload AccountSearchRequest request) {
logger.info("Received request | debtornum - " + request.getDebtornum());
AccountSearchResponse accountSearchResponse = objectFactory.createAccountSearchResponse();
AccountDetailsType accountDetails = accountService.getAccountDetails(request.getDebtornum());
accountSearchResponse.setAccountDetails(accountDetails);
logger.info("Returned response | status - " + accountSearchResponse.getAccountDetails().getDebtorStatus().value());
return accountSearchResponse;
}
这是包含被模拟的 DAO 的服务类
@Service
public class AccountServiceImpl implements AccountService {
//Autowired on a setter
private AccountServiceDao accountServiceDao;
Logger logger = LoggerFactory.getLogger(AccountServiceImpl.class);
@Override
public AccountDetailsType getAccountDetails(BigInteger accountNumber) {
........................
通过调试,我可以看到模拟 DAO 被正确注入,但我不知道如何设置模拟对象的行为。
对于我的单元测试,我能够做到以下几点:
accountDao = EasyMock.createMock(AccountServiceDao.class);
EasyMock.expect(accountDao.checkAccountExists(new BigInteger("12345678"))).andReturn(new Account(new BigInteger("12345678"),"Y",1,0,0,0,"ROI","ROI","DO","10012054082","POST","DD","John Doe","a@a.com","123456"));
EasyMock.replay(accountDao);
testSvc.setAccountServiceDao(accountDao);
当模拟通过 spring xml 配置自动装配时,我不确定如何进行相同的配置。我可能遗漏了一些明显或误解 EasyMock 的内容,但我们将不胜感激任何帮助或指导。
谢谢
【问题讨论】:
-
从您的 Context 文件和虚拟测试的外观来看,您似乎没有要注入的
ApplicationContext对象的 bean。如果您想在测试中使用模拟AccountServiceDao,则将其自动连接到测试中。 -
嗨,丹,感谢您的回复。 applicationContext 正在根据 applicationContext_test.xml 配置自动装配。我在这个 XML 中明确定义了两个 bean,一个用于模拟 DAO,另一个用于使用内存 DB 的 DAO。模拟的自动装配不是问题,我可以看到它已通过调试注入。但是,我不知道如何在这种类型的设置中配置模拟的行为。通常,我会在我的测试中明确定义模拟对象,对其进行配置,然后使用 set 方法。当你在 XML 中定义 mock 并自动装配它时,你在哪里配置它?
-
如果您要配置(设置期望)的对象被正确注入并且是一个 EasyMock 模拟,那么您只需像往常一样添加您的期望,然后像往常一样在其他对象上设置模拟(或者在测试或@Before 方法中)。这里唯一的区别是 Spring 基本上已经为您拨打了
EasyMock.createMock()电话。另一点:我不完全确定为什么,但我一直被告知要始终在 Spring 注入的模拟对象上使用EasyMock.reset(),以防 Spring 在进入测试类之前调用了模拟上的任何方法 -
谢谢丹,重置的东西可能正在接近货物崇拜。我让它与
AccountServiceDao svcDao = (AccountServiceDao)applicationContext.getBean("accountServiceDao");一起工作,然后将期望设置在svcDao上。谈到.getBean(),我有一点心理障碍。我从来没有觉得使用它很合适。
标签: spring testing jaxb spring-ws easymock