我有一个抽象类 AbstractService 和几个扩展该抽象类的类:
然后,我有一个 ServiceFactory,根据我传递的参数,它返回包含一些服务的通用列表:
public class ServiceFactory {
public List<? extends AbstractService> getServices(final MyParameter param) {
// Service is an interface implemented by AbstractService
List<Service> services = new ArrayList<>();
for (Foo foo : param.getFoos()) {
services.add(new AService(foo.getBar()));
}
// creates the rest of the services
return services;
}
}
在我的 UnitTest 中,我想验证我的服务列表是否恰好包含 3 个 AService 子类型。我现在的做法是:
@Test
public void serviceFactoryShouldReturnAServiceForEachFoo() {
// I'm mocking MyParameter and Foo here
Mockito.when(param.getFoos()).thenReturn(Arrays.asList(foo, foo, foo);
AService aservice = new AService(foo);
List<AService> expectedServices = Arrays.asList(aservice, aservice, aservice);
List<? extends AbstractService> actualServices = serviceFactory.getServices();
assertTrue(CollectionUtils.isSubCollection(expectedServices, actualServices));
}
当actualServices包含少于3个Aservice时,测试正确失败。这个解决方案的唯一问题是,如果actualServices包含超过3个AService,则测试通过......
是否有一种方法可以做到这一点,或者我应该使用循环自己实现它?
最佳答案
您可以使用 hamcrest Matchers。
hamcrest-library包含匹配器来检查集合/可迭代内容。
我希望以下示例与您的场景大致匹配
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.mockito.Mockito.mock;
import static org.hamcrest.Matchers.containsInAnyOrder;
import java.util.ArrayList;
import java.util.Collection;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.junit.Test;
public class ServiceFactoryTest
{
@Test
public void serviceFactoryShouldReturnAServiceForEachFoo()
{
Foo foo = mock( Foo.class );
Service service = new AService( foo );
Service[] expected = { service, service, service };
Service[] tooFew = { service, service };
Service[] tooMany = { service, service, service, service };
ServiceFactory factory = new ServiceFactory();
assertThat( factory.createServices( foo, foo, foo ), containsInAnyOrder( expected ) );
assertThat( factory.createServices( foo, foo, foo ), not( containsInAnyOrder( tooFew ) ) );
assertThat( factory.createServices( foo, foo, foo ), not( containsInAnyOrder( tooMany ) ) );
}
interface Foo
{}
interface Service
{}
class AService implements Service
{
Foo foo;
public AService( Foo foo )
{
this.foo = foo;
}
@Override
public boolean equals( Object that )
{
return EqualsBuilder.reflectionEquals( this, that );
}
}
class ServiceFactory
{
Collection<? extends Service> createServices( Foo... foos )
{
Collection<Service> list = new ArrayList<>();
for ( Foo foo : foos )
{
list.add( new AService( foo ) );
}
return list;
}
}
}
关于java - 如何测试泛型列表是否包含 Java 中子类型的确切子集合?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21284859/