【问题标题】:How to set EasyMock expectations after @Autowired injection?@Autowired 注入后如何设置 EasyMock 期望值?
【发布时间】: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


【解决方案1】:

根据上面 Dan 的评论,我的期望如下:

@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);

        //get the mocked bean from the applicationContext
        AccountServiceDao svcDao = (AccountServiceDao)applicationContext.getBean("accountServiceDao");

        //reset just in case
        EasyMock.reset();

        //set expectations on the mock
        EasyMock.expect(svcDao.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(svcDao);
    }

    @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));
    }
}

工作正常。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多