尝试使用测试驱动的开发并遇到了我无法解决的NPE,显然是因为我的一项测试失败。
在一种获取项目的方法中,我传入了一个limit int,然后实例化一个回调。
这正是我认为侦听器返回null的地方。
[![在此处输入图片描述] [1]] [1]
测试类
打包com.techyourchance.testdrivendevelopment.example11;
Serial
@RunWith(MockitoJUnitRunner.class)
public class FetchCartItemsUseCaseTest {
public static final int LIMIT = 10;
public static final int PRICE = 5;
public static final String ID = "id";
public static final String TITLE = "title";
public static final String DESCRIPTION = "description";
FetchCartItemsUseCase SUT;
@Mock
FetchCartItemsUseCase.Listener mListnerMock1;
FetchCartItemsUseCase.Listener mListnerMock2;
@Mock
GetCartItemsHttpEndpoint mGetCartItemsHttpEndpointMock;
@Captor
ArgumentCaptor<List<CartItem>> mAcListCartItem;
@Before
public void setup() throws Exception {
SUT = new FetchCartItemsUseCase(mGetCartItemsHttpEndpointMock);
success();
}
private void success() {
doAnswer(new Answer() {
@Override
public Object answer(InvocationOnMock invocation) throws Throwable {
Object[] args = invocation.getArguments();
Callback callback = (Callback) args[1];
callback.onGetCartItemsSucceeded(getCartItemSchemes());
return null;
}
}).when(mGetCartItemsHttpEndpointMock).getCartItems(anyInt(), any(Callback.class));
}
private List<CartItemSchema> getCartItemSchemes() {
List<CartItemSchema> schemas = new ArrayList<>();
schemas.add(new CartItemSchema(ID, TITLE, DESCRIPTION, PRICE));
return schemas;
}
@Test
public void fetchCartItems_correctLimitPassedToEndPoint() throws Exception {
ArgumentCaptor<Integer> acInt = ArgumentCaptor.forClass(Integer.class);
SUT.fetchCartItemsAndNotify(LIMIT);
verify(mGetCartItemsHttpEndpointMock).getCartItems(acInt.capture(), any(GetCartItemsHttpEndpoint.Callback.class));
assertThat(acInt.getValue(), is(LIMIT));
}
@Test
public void fetchCartItems_success_observersNotifiedWithCorrectData() throws Exception {
SUT.registerListener(mListnerMock1);
SUT.registerListener(mListnerMock2);
SUT.fetchCartItemsAndNotify(LIMIT);
verify(mListnerMock1).onCartItemsFetched(mAcListCartItem.capture());
verify(mListnerMock2).onCartItemsFetched(mAcListCartItem.capture());
List<List<CartItem>> captures = mAcListCartItem.getAllValues();
List<CartItem> capture1 = captures.get(0);
List<CartItem> capture2 = captures.get(1);
assertThat(capture1, is(getCartItems()));
assertThat(capture2, is(getCartItems()));
}
private List<CartItem> getCartItems() {
List<CartItem> cartItems = new ArrayList<>();
cartItems.add(new CartItem(ID, TITLE, DESCRIPTION, PRICE));
return cartItems;
}
//correct limit passed to the endpoint
//success - all observers notified with correct data
//success - unsubscribed observers not notified
//general error - observers notified of failure
//network error - observers notified of failure
}
public class FetchCartItemsUseCase {
private final List<Listener> mListeners = new ArrayList<>();
private final GetCartItemsHttpEndpoint mGetCartItemsHttpEndpoint;
public FetchCartItemsUseCase(GetCartItemsHttpEndpoint mGetCartItemsHttpEndpoint) {
this.mGetCartItemsHttpEndpoint = mGetCartItemsHttpEndpoint;
}
public void fetchCartItemsAndNotify(int limit) {
mGetCartItemsHttpEndpoint.getCartItems(limit, new GetCartItemsHttpEndpoint.Callback() {
@Override
public void onGetCartItemsSucceeded(List<CartItemSchema> cartItems) {
for(Listener listener : mListeners) {
listener.onCartItemsFetched(cartItemsFromSchemas(cartItems));
}
}
@Override
public void onGetCartItemsFailed(GetCartItemsHttpEndpoint.FailReason failReason) {
}
}) ;
}
private List<CartItem> cartItemsFromSchemas(List<CartItemSchema> cartItemSchemas) {
List<CartItem> cartItems = new ArrayList<>();
for(CartItemSchema schema : cartItemSchemas) {
cartItems.add(new CartItem(schema.getId(), schema.getTitle(),
schema.getDescription(), schema.getPrice()));
}
return cartItems;
}
public void registerListener(Listener listener) {
mListeners.add(listener);
}
public interface Listener {
Void onCartItemsFetched(List<CartItem> capture);
}
}
[1]: https://i.stack.imgur.com/r6Sea.png
really lost would appreciate any help