CloudStack 4.1 has switched over to using Spring for component injection and aop.  This makes it much more flexible in terms of working with Junit.  This page details how to write a junit test.  This assumes you're already familiar with JUnit.  Please note the comments // NOTE # which indicates what has been added to this file.

// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.
package org.apache.cloudstack.affinity;

import ...;

@RunWith(SpringJUnit4ClassRunner.class)// NOTE #1
@ContextConfiguration(loader = AnnotationConfigContextLoader.class) // NOTE #2
public class AffinityApiUnitTest {

    AffinityGroupService _affinityService;

    AccountManager _acctMgr;

    AffinityGroupProcessor _processor;

    AffinityGroupDao _groupDao;

    UserVmDao _vmDao;

    AffinityGroupVMMapDao _affinityGroupVMMapDao;

    AffinityGroupDao _affinityGroupDao;

    EventUtils _eventUtils;

    AccountDao _accountDao;

    EventDao _eventDao;

    private static long domainId = 5L;

    public static void setUp() throws ConfigurationException {

    public void testSetUp() {
        ComponentContext.initComponentsLifeCycle();  // NOTE #3
        AccountVO acct = new AccountVO(200L);

        UserContext.registerContext(1, acct, null, true);

        when(_acctMgr.finalizeOwner((Account) anyObject(), anyString(), anyLong(), anyLong())).thenReturn(acct);

        AffinityGroupVO group = new AffinityGroupVO("group1", "mock", "mock group", domainId, 200L);
        Mockito.when(_affinityGroupDao.findByAccountAndName(Mockito.anyLong(), Mockito.anyString())).thenReturn(group);
        Mockito.when(_affinityGroupDao.lockRow(Mockito.anyLong(), anyBoolean())).thenReturn(group);
        Mockito.when(_eventDao.persist(Mockito.any(EventVO.class))).thenReturn(new EventVO());

    public void createAffinityGroupTest() {
        when(_groupDao.isNameInUse(anyLong(), anyLong(), eq("group1"))).thenReturn(false);
        AffinityGroup group = _affinityService.createAffinityGroup("user", domainId, "group1", "mock",
                "affinity group one");
        assertNotNull("Affinity group 'group1' of type 'mock' failed to create ", group);


    @Test(expected = InvalidParameterValueException.class)
    public void invalidAffinityTypeTest() {
        AffinityGroup group = _affinityService.createAffinityGroup("user", domainId, "group1", "invalid",
                "affinity group one");


    @Test(expected = InvalidParameterValueException.class)
    public void uniqueAffinityNameTest() {
        when(_groupDao.isNameInUse(anyLong(), anyLong(), eq("group1"))).thenReturn(true);
        AffinityGroup group2 = _affinityService.createAffinityGroup("user", domainId, "group1", "mock",
                "affinity group two");

    @Test(expected = InvalidParameterValueException.class)
    public void deleteAffinityGroupInvalidIdTest() throws ResourceInUseException {
        _affinityService.deleteAffinityGroup(20L, "user", domainId, "group1");

    @Test(expected = InvalidParameterValueException.class)
    public void deleteAffinityGroupInvalidIdName() throws ResourceInUseException {
        when(_groupDao.findByAccountAndName(200L, "group1")).thenReturn(null);
        _affinityService.deleteAffinityGroup(null, "user", domainId, "group1");

    @Test(expected = InvalidParameterValueException.class)
    public void deleteAffinityGroupNullIdName() throws ResourceInUseException {
        _affinityService.deleteAffinityGroup(null, "user", domainId, null);

    @Test(expected = ResourceInUseException.class)
    public void deleteAffinityGroupInUse() throws ResourceInUseException {
        List<AffinityGroupVMMapVO> affinityGroupVmMap = new ArrayList<AffinityGroupVMMapVO>();
        AffinityGroupVMMapVO mapVO = new AffinityGroupVMMapVO(20L, 10L);

        AffinityGroupVO groupVO = new AffinityGroupVO();
        when(_groupDao.lockRow(20L, true)).thenReturn(groupVO);

        _affinityService.deleteAffinityGroup(20L, "user", domainId, null);

    @Test(expected = InvalidParameterValueException.class)
    public void updateAffinityGroupVMRunning() throws ResourceInUseException {

        UserVmVO vm = new UserVmVO(10L, "test", "test", 101L, HypervisorType.Any, 21L, false, false, domainId, 200L,
                5L, "", "test", 1L);

        List<Long> affinityGroupIds = new ArrayList<Long>();

        _affinityService.updateVMAffinityGroups(10L, affinityGroupIds);

    @ComponentScan(basePackageClasses = {AffinityGroupServiceImpl.class, EventUtils.class}, includeFilters = {@Filter(value = TestConfiguration.Library.class, type = FilterType.CUSTOM)}, useDefaultFilters = false)
    public static class TestConfiguration extends SpringUtils.CloudStackTestConfiguration { // NOTE #4

        public AccountDao accountDao() {
            return Mockito.mock(AccountDao.class);

        public AccountService accountService() {
            return Mockito.mock(AccountService.class);

        public AffinityGroupProcessor affinityGroupProcessor() {
            return Mockito.mock(AffinityGroupProcessor.class);

        public AffinityGroupDao affinityGroupDao() {
            return Mockito.mock(AffinityGroupDao.class);

        public AffinityGroupVMMapDao affinityGroupVMMapDao() {
            return Mockito.mock(AffinityGroupVMMapDao.class);

        public AccountManager accountManager() {
            return Mockito.mock(AccountManager.class);

        public EventDao eventDao() {
            return Mockito.mock(EventDao.class);

        public UserVmDao userVMDao() {
            return Mockito.mock(UserVmDao.class);

        public static class Library implements TypeFilter {

            public boolean match(MetadataReader mdr, MetadataReaderFactory arg1) throws IOException {
                ComponentScan cs = TestConfiguration.class.getAnnotation(ComponentScan.class);
                return SpringUtils.includedInBasePackageClasses(mdr.getClassMetadata().getClassName(), cs);

The above example demonstrates a single self-contained unit test.  It not only contains the unit test but also the spring configuration necessary to inject all of the necessary components.  The configuration is contained inside the Java class TestConfiguration.  Let's go over each note as commented in the code.

NOTE #1: Specifying @RunWith denotes a junit test@RunWith(SpringJUnit4ClassRunner.class)

NOTE #2: ContextConfiguration tells Spring where to find the component configuration for this Junit test.  AnnotationConfigContextLoader.class specifies that the test configuration exists within this class.@ContextConfiguration(loader = AnnotationConfigContextLoader.class)

NOTE #3: You need to initComponentsLifeCycle in setup because that causes all of the components injected follows CloudStack's life cycle management.ComponentContext.initComponentsLifeCycle();

NOTE #4: TestConfiguration Class tells Spring the configuration you want to use for this Junit test.  Note the following things in the class.

  • It is annotated with @Configuration.
  • @ComonentScan tells Spring which components should be loaded.  Note that Spring notes all classes in the package of the class specified so it can load too many classes.  To avoid this, specify the includeFilters as in the example above and useDefaultFilters=false in the @ComponentScan annotation.  What this does is makes sure only the classes specified in @ComponentScan is loaded and not other classes in the same package.
  • Extend SpringUtils.CloudStackConfiguration to get all the transaction handling etc.
  • Use Mockito to mock up the components that you don't want to test.
  • Specify the Library if you used includeFilters in the @ComponentScan annotation.  Just copy this class into your TestConfiguration.  Make sure the class is public static.


Besides these, if the method you need to unit test has @DB annotation, then you also need to make the following changes:

  • Add the following dependency to your pom.xml:








  • Create a "test/resources" folder with a file that can be copied from utils/conf/
  • No labels