我有一个演员类EmployeeActor
,在该演员内部,使用payrollRunActor.tell()
触发了其他演员。我需要为EmployeeActor.java
编写一个 JUnit 测试,但我不想解雇payrollRunActor.tell()
,这意味着我想嘲笑它。
有没有办法做到这一点?我尝试了很多,但真正的payrollRunActor
被解雇了。这是我EmployeeActor
类的实际代码。
包装 com.test.periodic.actor;
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();
}
}
首先,您必须模拟在创建待测试类期间调用的静态方法调用。然后让它返回一个被监视的对象,并模拟你想要避免调用的方法:
@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
而不是间谍。