@Test public void pickFruits() { final FruitTree mangoTree = context.mock(FruitTree.class); final Mango mango1 = new Mango(); final Mango mango2 = new Mango(); context.checking( new Expectations() { { oneOf(mangoTree).pickFruit(with(any(Collection.class))); will( new VoidAction() { public Object invoke(Invocation invocation) { @SuppressWarnings({"unchecked"}) Collection<Fruit> fruits = (Collection<Fruit>) invocation.getParameter(0); fruits.add(mango1); fruits.add(mango2); return null; } }); } }); Collection<Fruit> fruits = new FruitPicker().pickFruits(asList(mangoTree)); assertEquals(asList(mango1, mango2), fruits); }
@Test public void willAnnounceItHasFinishedIfPriceGoesAboveMaximum() { context.checking( new Expectations() { { exactly(1).of(listener).sniperFinished(sniper); } }); sniper.bidAccepted(unbeatableBid); }
@Test public void willLimitBidToMaximum() throws Exception { context.checking( new Expectations() { { exactly(1).of(auction).bid(maximumBid); } }); sniper.bidAccepted(maximumBid.subtract(new Money(1))); }
@Test public void willNotBidPriceGreaterThanMaximum() throws Exception { context.checking( new Expectations() { { ignoring(listener); never(auction).bid(with(any(Money.class))); } }); sniper.bidAccepted(unbeatableBid); }
@Test public void triesToBeatTheLatestHighestBid() throws Exception { final Money expectedBid = beatableBid.add(increment); context.checking( new Expectations() { { oneOf(auction).bid(expectedBid); } }); sniper.bidAccepted(beatableBid); }
@Test public void catchesExceptionsAndReportsThemToErrorListener() throws Exception { final AuctionException exception = new AuctionException("test"); context.checking( new Expectations() { { allowing(auction).bid(with(any(Money.class))); will(throwException(exception)); exactly(1).of(listener).sniperBidFailed(sniper, exception); } }); sniper.bidAccepted(beatableBid); }
@Test public void modelBlowsUpInAnUnavoidableWay() throws Exception { mockery.checking( new Expectations() { { allowing(browseTransactionsModel).findAllTransactions(); will(throwException(new InternalStorageException())); } }); pressExportAllTransactionsButton(browseTransactionsActivity); assertLastToastMatchesRegex( "Something strange just happened. Try again. You might need to reinstall the " + "application. I feel embarrassed and ashamed."); }
@Test public void exportWhateverTheModelProvides() throws Exception { final List<Transaction> anyNonEmptyListOfTransactions = ObjectMother.anyNonEmptyListOfTransactions(); mockery.checking( new Expectations() { { allowing(browseTransactionsModel).findAllTransactions(); will(returnValue(anyNonEmptyListOfTransactions)); ignoring(androidDevicePublicStorageGateway); oneOf(exportAllTransactionsAction).execute(with(anyNonEmptyListOfTransactions)); } }); pressExportAllTransactionsButton(browseTransactionsActivity); }
@Test public void mediaNotAvailable() throws Exception { mockery.checking( new Expectations() { { allowing(browseTransactionsModel).findAllTransactions(); allowing(androidDevicePublicStorageGateway).findPublicExternalStorageDirectory(); will(throwException(new PublicStorageMediaNotAvailableException())); never(exportAllTransactionsAction); } }); pressExportAllTransactionsButton(browseTransactionsActivity); assertLastToastMatchesRegex( "No place to which to export the transactions. Insert an SD card or connect an " + "external storage device and try again."); }
@Test public void exportActionBlowsUpInAnUnavoidableWay() throws Exception { mockery.checking( new Expectations() { { // SMELL How can I ignore these irrelevant details? ignoring(browseTransactionsModel); ignoring(androidDevicePublicStorageGateway); allowing(exportAllTransactionsAction).execute(with(any(List.class))); will(throwException(new InternalStorageException())); } }); pressExportAllTransactionsButton(browseTransactionsActivity); assertLastToastMatchesRegex( "Something strange just happened. Try again. You might need to reinstall the " + "application. I feel embarrassed and ashamed."); }
@Test public void mediaNotWritable() throws Exception { mockery.checking( new Expectations() { { allowing(browseTransactionsModel).findAllTransactions(); allowing(androidDevicePublicStorageGateway).findPublicExternalStorageDirectory(); will( throwException( new PublicStorageMediaNotWritableException( new File("/mnt/sdcard/TrackEveryPenny.csv")))); never(exportAllTransactionsAction); } }); pressExportAllTransactionsButton(browseTransactionsActivity); assertLastToastMatchesRegex( "Permission denied trying to export the transactions to file " + "/mnt/sdcard/TrackEveryPenny.csv"); }
@Test public void happyPath() throws Exception { final Collection<Object> anyValidNonTrivialCollectionOfTransactions = Lists.newArrayList(new Object(), new Object(), new Object()); mockery.checking( new Expectations() { { allowing(browseTransactionsModel).findAllTransactions(); will(returnValue(anyValidNonTrivialCollectionOfTransactions)); // SMELL Irrelevant detail ignoring(androidDevicePublicStorageGateway).findPublicExternalStorageDirectory(); allowing(exportAllTransactionsAction).execute(with(any(List.class))); // succeeds by not throwing an exception } }); pressExportAllTransactionsButton(browseTransactionsActivity); assertLastToastMatchesRegex("Exported all transactions to (.+)\\.csv"); }