在Actor类中模拟actorRef.tell

时间:2017-06-21 13:44:20

标签: java unit-testing akka mockito powermock

我有一个演员类EmployeeActor,在该演员中,其他一些演员被payrollRunActor.tell()解雇。我需要为EmployeeActor.java编写一个JUnit测试,但是我不想解雇payrollRunActor.tell(),这意味着我想要嘲笑它。

有办法吗?我尝试了很多,但真正的payrollRunActor被解雇了。 这是我的EmployeeActor类的实际代码。

package com.test.periodic.actors;

import java.util.List;

import org.apache.commons.lang3.RandomStringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.test.avs.domain.boundedcontext.Employee;
import com.test.avs.domain.boundedcontext.PayrollRun;
import com.test.entity.BusinessDTO;
import com.test.periodic.actors.aggregrators.EmployeeAggregator;

import akka.actor.AbstractActor;
import akka.actor.ActorRef;
import akka.actor.ActorSystem;
import akka.actor.Props;
import akka.routing.RoundRobinPool;

public class EmployeeActor extends AbstractActor {
    private static final Logger logger = LoggerFactory.getLogger(EmployeeActor.class);
    private boolean rollup;

    public static Props props() {
        return Props.create(EmployeeActorTest.class);
    }

    private List<PayrollRun> payrollRuns;
    private String instanceId;
    private String employeeAggregatorId;
    private Employee employee;
    private ActorRef organizationAggregatorActor;
    private List<BusinessDTO> businessDTOs;

    final ActorSystem payrollRunSystem = ActorSystem.create("payrollRun");

    ActorRef employeeAggregator;

    public EmployeeActor(ActorRef organizationAggregatorActor, List<PayrollRun> payrollRuns,
            Employee employee, List<BusinessDTO> businessDTOs, boolean rollup) {
        this.payrollRuns = payrollRuns;
        this.employee = employee;
        this.organizationAggregatorActor = organizationAggregatorActor;
        this.businessDTOs = businessDTOs;
        this.rollup = rollup;
    }

    @Override
    public void preStart() throws Exception {
        instanceId = RandomStringUtils.randomAlphanumeric(6);
        employeeAggregatorId = "employeeAggregator-" + instanceId;
        employeeAggregator = getContext().system().actorOf(
                Props.create(EmployeeAggregator.class, organizationAggregatorActor, employee),
                employeeAggregatorId);
        super.preStart();
    }

    @Override
    public Receive createReceive() {
        return receiveBuilder().match(Employee.class, employee -> {

            if (rollup) {
                logger.info("Rollingup business entities.");
                employeeAggregator.tell(employee, getSelf());
            } else {
                ActorRef payrollRunActor = payrollRunSystem.actorOf(new RoundRobinPool(payrollRuns.size())
                        .props(Props.create(PayrollRunActor.class, employeeAggregator, employee, businessDTOs)));
                for (PayrollRun payrollRun : payrollRuns) {
                    **payrollRunActor.tell(payrollRun, getSelf());**
                }
            }


        }).match(PayrollRun.class, maxPaydatePayrollRun -> {
            ActorRef payrollRunActor = payrollRunSystem
                    .actorOf(Props.create(PayrollRunActor.class, employeeAggregator, employee, businessDTOs));
            **payrollRunActor.tell(maxPaydatePayrollRun, getSelf());**
        }).build();
    }
}

1 个答案:

答案 0 :(得分:0)

首先,您必须模拟在创建测试类期间调用的静态方法调用。然后让它返回一个spied对象并模拟你想要避免调用的方法:

@RunWith(PowerMockRunner.class)
@PrepareForTest(ActorSystem.class)
public void TestClass{

     @Test
     public void test(){
          // Arrange
          PowerMockito.mockStatic(ActorSystem.class);
          ActorSystem actorSystemMock = Mockito.mock(ActorSystem.class);
          Actor actorSpy = Mockito.spy(new Actor());

          Mockito.when(ActorSystem.create("payrollRun")).thenReturn(actorSystemSpy);

          Mockito.when(actorSystemMock.actorOf(any(RoundRobinPool.class)))
            .thenReturn(actorSpy);     

          Mockito.doNothing().when(actorSpy)
            .tell(Mockito.any(PayrollRun.class), Mockito.any(Self.class));

          EmployeeActor employeeActor = new EmployeeActor(); 

          // Act and assert...
          employeeActor.createReceive();
     }
}

请记住,将调用actorSystemSpy的所有其他方法将实际实现。如果你想模仿所有这些,那么使用Mockito.mock代替间谍。