text:
Show Transcript Hide Transcript
Let's consider employment. Wage increases have, unfortunately, been sluggish.
When you go in to talk about a new position or to talk about continuing to work for your same employer you really need to be aggressive about asking for a raise.
People who negotiate actually get $5,000 more on average than people who don't negotiate.
If you don't ask, they answer is always going to be "no."
Let's consider employment. Wage increases have, unfortunately, been sluggish.
When you go in to talk about a new position or to talk about continuing to work for your same employer you really need to be aggressive about asking for a raise.
People who negotiate actually get $5,000 more on average than people who don't negotiate.
If you don't ask, they answer is always going to be "no."
If you're intimidated by the rising cost of college tuition, you're not alone. Data released from the research and advocacy group, Young Invincibles, show that college tuition and fees at public universities have risen an average of 28% since 2008, with states such as Georgia and Arizona raising prices by 68% and 72%, respectively. But don't stress yet; there are ways to fight college tuition inflation.
Here are the best tips on how to pay for college in 2016.
Jeff Greenberg/Universal Images Group Editorial/Getty Images
"It is advantageous for students to apply for scholarships early," says Kelly Tanabe, co-author of "Get Free Cash for College: Secrets to Winning Scholarships." "There are some scholarship programs that place limits on the number of applications they will consider. So if you delay applying, it's possible that your application will not be accepted."
Early birds also have an advantage when applying for federal student aid, Tanabe says. While private scholarships have their own application deadlines, students can apply for federal financial aid, starting Jan. 1. Since some federal awards are given out on a first-come, first-served basis, applying early can pay off.
Where you save can count just as much as how much you save. To make sure that your college savings aren't detracting from your family's financial aid package, Joe Hurley, founder of SavingForCollege.com, recommends that families place their assets in accounts held in the parents' names.
"The first dollar of (assets held in the student's name) will impact a family's expected contribution," says Hurley. "That can lower the financial aid package."
Student assets -- any cash stored in a checking or savings account, a business venture, real estate, or an investment in the child's name -- are assessed at a rate of 20%. That means that for every dollar the student saves, the federal government will subtract 20 cents of every dollar in the student's financial aid package. The assessment rate for parental assets is much less stringent. A maximum of 5.64% of a parent's assets are assessed on the Free Application for Federal Student Aid.
The 2 exceptions are 529 college savings plans and Coverdell education savings accounts, Hurley says. Funds in these types of accounts are assessed at the parental rate, regardless of whether they're held in the student's or parent's name.
One major drawback of working in public service is that the salaries that come with jobs in fields such as social work, public defense and education are sometimes substantially lower than salaries in other fields.
If student debt is holding you back from pursuing a public service job, the government is here to help. Under the federal Public Service Loan Forgiveness Program, students who have direct loans (which are only federal loans, not private) and who work full time in public service fields are eligible to have any leftover federal debt forgiven after they make consecutive payments for 10 years.
To sweeten the deal, borrowers also can apply for any of the federal income-driven repayment plans, which set student loan payments at between 10% and 20% of their discretionary income, depending on the plan. Under income-driven repayment plans, the lowest-earning borrowers won't have to make student loan payments at all.
RATE SEARCH: Find the best rates on personal loan to pay for college now at Bankrate.com.
The U.S. government defines "discretionary income" as earnings greater than 150% of the poverty line for your family size and state of residence. For a single-person family living in the contiguous states, 150% of the poverty line equals $17,820. Borrowers earning less than that will have a monthly payment set at zero, but will still have those free payments count toward loan forgiveness. Any forgiven debt under Public Service Loan Forgiveness is not taxable by the IRS.
The federal financial aid formula considers assets such as stocks, mutual funds, certificates of deposit and rental properties that your family owns, but some other investment vehicles such as retirement plans, life insurance plans and equity in your family's primary residence aren't included in the federal financial aid formula.
Kalman Chany, author of "Paying for College Without Going Broke," says that parents may, but don't always, qualify for more financial aid if they store assets in places that aren't considered on the FAFSA. That includes paying off unsecured debt such as personal loans. Money also owed to credit card companies or on auto loans aren't considered in the federal needs formula.
"Let's say you have $10,000 in cash and $10,000 in credit card debt and $100,000 in other reportable assets," Chany says. "If you plan to use the cash to pay off the debt but you turn in the (FAFSA) forms beforehand, you're going to be assessed for that cash."
"But if you pay off your debt with that cash before you turn in the form, you could be eligible for more aid," Chany says.
Parents and students don't have to shoulder the burden of college costs alone. Grandparents, family members and even benevolent strangers can contribute to a student's 529 plan, and there are perks built in for those who give big.
The IRS reports that individuals can give financial gifts up to $14,000 per year per beneficiary to a 529 plan, without paying a gift tax.
All 529 plans come with an additional caveat that allows donors to give a financial gift of up to 5 years of funds at a time -- $70,000 for individuals, $140,000 for married couples -- without incurring gift taxes as long as the total amount of the gift averages out to $14,000 per year over a 5-year period. That means that if a relative donates $50,000 to your child's 529 in 2016, he can donate only $20,000 over the next 4 years.
The FAFSA -- the document that makes students eligible for federal grants and loans -- looks intimidating, but that shouldn't scare students away.
RATE SEARCH: Compare interest rates on personal loans for college now to find the best.
"There are a lot of myths about the FAFSA -- it's really arduous, it's hard to fill out, it will take forever," says Melanie Heath, spokeswoman for the Utah System of Higher Education. "Really it takes about half an hour, and based on your financial need, you can qualify for over $5,000 in Pell Grants. In Utah, at many of our public institutions, that would pay for an entire year of tuition."
The FAFSA not only qualifies students for federal aid, it also may qualify students for awards given out through their colleges or through private scholarship programs.
"You should definitely complete the FAFSA, even if you think you won't qualify for federal aid," author Tanabe says. "In financial aid, there are many factors taken into consideration, including income, assets and number of students (living in your home). While you may think that one of these factors is too high for you to receive aid, when the financial aid officer looks at your entire financial picture, you may have more need than you think."
Colleges and universities vary dramatically in how much financial aid they have to give. Certain schools, such as the Webb Institute in Glen Cove, New York, and the Curtis Institute of Music in Philadelphia, offer full-tuition scholarships to every admitted student, while some "work colleges," such as College of the Ozarks in Point Lookout, Missouri, offer free or reduced tuition in exchange for student work.
Tuition-free colleges are rare. Even historically free schools such as the Cooper Union for the Advancement of Science and Art in New York and Franklin W. Olin College of Engineering in Needham, Massachusetts, have started charging some tuition in recent years.
Still, many pricey institutions offer deep discounts to low- and moderate-income students. Head to Nces.ed.gov/collegenavigator to research average financial aid packages by income bracket.
The golden rule of college finance still rings true for 2016: Start saving early to maximize the compound interest. According to Bankrate.com's college savings calculator, parents who start investing $200 per month when their child is born will have about $79,500 in that account by the time their child turns 18, assuming a 6% rate of return. Families who wait to start investing will need to stash a lot more cash to make up for the time difference.
Assuming the same rate of return, parents who begin investing when their child is 10 years old will need to save $650 per month -- more than 3 times the amount of the early bird family -- to accumulate the same level of college savings.
The best way to maximize your chances for winning a scholarship is to first apply for those you're most likely to win. According to Tanabe, that means applying for federal aid first, hitting up your college of choice for funds and rooting out awards offered through local organizations, clubs and professional groups.
"You're going to have a much higher likelihood of getting a scholarship that fewer people are applying for," she says.
Some 529 college savings plans vary dramatically on fees, investment options, tax incentives and rates of return. While some offer generous state tax deductions, others offer little or no state tax incentives.
When comparing plans, Heath of the Utah System of Higher Education recommends researching 529 plan ratings through organizations such as Morningstar, looking into your home state's 529 plans first to figure out what state tax incentives you may be eligible for and remembering that you can invest in any state's 529 plan, not just where you reside.
"(529) funds can be used at any institution that accepts federal aid," Tanabe says. "That gives you a huge amount of institutions to choose from across the nation."
Bankrate wants to hear from you and encourages thoughtful and constructive comments. We ask that you stay focused on the story topic, respect other people's opinions, and avoid profanity, offensive statements, illegal contents and advertisement posts. Comments are not reviewed before they are posted. Bankrate reserves the right (but is not obligated) to edit or delete your comments. Please avoid posting private or confidential information, and also keep in mind that anything you post may be disclosed, published, transmitted or reused. We do not permit the inclusion of hyperlinks in comments and may remove any comment that includes a hyperlink.
By submitting a post, you agree to be bound by Bankrate's terms of use. Please refer to Bankrate's privacy policy for more information regarding Bankrate's privacy practices.


text:
Sleep supplements at a low price?! Check. Whether you're looking for melatonin, valerian root, l-tryptophan, 5-HTP or a sleep combination formula, Swanson Health Products has you covered. Browse gluten free, vegan and non-GMO formulas to suit your dietary needs. Get your favorites from Swanson Health Products, NOW Foods, Source Naturals and other popular brands today.
You're now signed up to receive exclusive deals and savings opportunities!
Thank you for your interest and be assured that you will continue to receive our emails at this address.
We are having trouble processing your request. Our apologies! Please try again later.

subset: commoncrawl


text:
They just got 4th vote they needed. Still going on.
They just got 4th vote they needed. Still going on.
The lowest acceptable payroll amount for ownership to show they are not greedy pigs is 15 million more than they are currently paying. No matter what that currently is.
Final vote was unanimous
The lowest acceptable payroll amount for ownership to show they are not greedy pigs is 15 million more than they are currently paying. No matter what that currently is.
Unfortunate, if you ask me...
"In our sundown perambulations of late, through the outer parts of Brooklyn, we have observed several parties of youngsters playing 'base', a certain game of ball. Let us go forth awhile, and get better air in our lungs. Let us leave our close rooms, the game of ball is glorious"
-Walt Whitman
Sounds like the Reds are probably headed to Arizona starting in 2010.
Goodyear City Council approved the Memorandum of Understanding, the big step in the bringing the Reds to Goodyear.
The vote was 6-0. Joanne Osborne, the council woman who said she was opposed a few weeks ago, was swayed in the last couple of weeks.
The city has stepped forward to fund the $33 million project.
John Allen was at the meeting he passed out Reds hats to the council members after the vote.
Extremely good news for me. I'll get to see the Reds play in my In-Laws' back yard.
Well, it looks like next year's ST will be the last for me. I feel more sorry for the fans who have followed the Reds in FL for decades. When I stayed at the Holiday Inn this year - a couple two doors down - were making their IIRC 10th trip and where going to the games with a couple making their 25th trip. Sad...
But on the bright side - I'll be saving over $2,000 in 2010!!!
2017 Reds record when I'm attending: 16-14 FINAL2017 Dragons record when I'm attending: 1-0 FINAL
"We want to be the band to dance to when the bomb drops." - Simon Le Bon of Duran Duran
I'm loving it. Taking a $149 RT dollar special on America West to Phoenix then renting a compact for 99 bucks and heading to Tucson. The Reds won't miss out on fans to watch - Arizona has thousands of Ohio ex-patriates. I lived in Yuma and Phoenix for four years and love the state so this is right up my alley. I do feel for the fans that drive to Florida but with the price of gas nowadays that may be more and more a burden on alot of fans, and airfares aren't much more expensive than driving. The fans I really feel bad for are the ones who have actually moved to Florida for retirement with Reds ST one of their criteria in choosing Florida. But now I know where my sunny retirement years are going to be!
Good news for me too. It's just a day's drive from where I live.
Last edited by BRM; 04-08-2008 at 10:11 AM.
Both sites are nearly equidistant from me, so I'm ambivalent about the location.
What I am excited about is the financial aspect of the deal. The Reds are getting a much nicer facility to prepare the major and minor league teams for their seasons and the organization will save millions on the rights to use it. That leaves the team with more money to spend on players and things in Cincinnati that will improve the fan experience. We need to remember this day in two years time when we're happy that the team's pockets seem so much deeper, because this deal will have contributed to that effect.
Wear gaudy colors, or avoid display. Lay a million eggs or give birth to one. The fittest shall survive, yet the unfit may live. Be like your ancestors or be different. We must repeat!
I'm disappointed but I'm not going to be retiring in 20 years anyway. There's just not much to do in Goodyear, AR. In Sarasota you've got beaches, boat rides, the Ringling Museum and a lot of nice restaurants with fresh fish. I don't want to hear any complaining from the Reds about lack of attendance in Goodyear.
This sucks. :thumbdown
Go BLUE!!!
Board Moderators may, at their discretion and judgment, delete and/or edit any messages that violate any of the following guidelines: 1. Explicit references to alleged illegal or unlawful acts. 2. Graphic sexual descriptions. 3. Racial or ethnic slurs. 4. Use of edgy language (including masked profanity). 5. Direct personal attacks, flames, fights, trolling, baiting, name-calling, general nuisance, excessive player criticism or anything along those lines. 6. Posting spam. 7. Each person may have only one user account. It is fine to be critical here - that's what this board is for. But let's not beat a subject or a player to death, please.


text:
Photo © 2007 Tom Kirsch
View full size photo
Use Your Facebook Profile
Use Your Facebook Profile:
Question:Is the color of the sky blue or green?
You've decided to leave a comment, yay! Please keep in mind that comments are moderated, and rel="nofollow" in in use. Full names or other personal information posted regarding current or former patients from hospitals or psychiatric facilities will be obscured or removed. Comments pertaining to real location names (when given a pseudonym), methods of entering the property, or just flaming will be deleted. So let's have meaningful conversations instead, thanks!


text:
BANTAM >> Two Torrington men were arrested in connection with a "string" of motor vehicle break-ins after a witness called police and reported watching the men open and rummage through unlocked cars.
Samuel J. Cosme, 21, and Gustavo Velazquez, 31, both of 363 South Main St., Torrington, second floor, were both charged with multiple counts of burglary, sixth-degree larceny and criminal possession of burglary tools after police responded to a caller who reported watching two men break into vehicles at about 2 a.m. Sunday.
The witness later identified vehicles he reported watching the two men break into, and police reported that the vehicles were unlocked and the interiors "disheveled."
Police reported both men were found with flashlights, iPhones, GPS systems and a large amount of change, about $8, which police suspect the men stole from vehicles. Two pairs of women's underwear were also seized from Cosme.
Cosme was later charged with additional burglary and larceny counts after a Warrenton Mill condominiums resident called police at about 8 a.m., reporting his GPS was missing and his car appeared to be broken into. Police said Cosme "admitted to taking the GPS," after being questioned.
In a press release, police wrote that the men's modus operandi matched a "string" of vehicle break-ins in the area.
In addition to burglary charges pending against Cosme, Torrington Police arrested and charged the man seven days prior on charges of third-degree larceny, operating a motor vehicle without a license, improper turn and failure to display lights.
Cosme is scheduled to appear in Bantam Superior Court on Aug. 7, Velazquez on Aug. 15. Cosme's bond was set at $2,500, and Velazquez at $5,000.


text:
Howe also won the consolation heat of the 100 fly in 1:00.78, while finishing ahead of Olympic medalist Rachel Bootsma and 2013 NCAA Swimmer of the Year Elizabeth Pelton, both from Cal. Elsewhere in the meet, 25-year-old Bernard Thompson of Palo Alto Stanford Aquatics (PASA) won the men's 200 breast in 2:14.51 and finished third in the 100 breast in 1:02.68. Stanford grad Eugene Godsoe was third in the men's 100 fly (53.28) with former teammate Bobby Bollier fourth in 53.82). Bollier also took third in the 200 fly (1:59.80) and Godsoe was third in the 100 back (54.77). Stanford freshman Tom Kremer from Sacred Heart Prep was the top qualifier in the 200 fly, but did not swim the final. He did compete in the 200 free, where he finished eighth in 1:51.73.
Menlo Park resident (and St. Francis student) Curtis Ogren splashed to a fourth place in the men's 400 (M (4:27.75) in addition to winning consolation honors in the 200 IM in 2:05.87, a time that would have gotten him sixth had he raced in the finals. Stanford's Geoff Cheah was sixth in the men's 50 free (23.28) and Palo Alto's Liv Jensen was sixth in the women's 50 free (26.05). Stanford grad Chad La Tourette was sixth in the 400 free in 4:00.32.
ON THE FIELD . . . Four-star football safety Brandon Simmons, a member of the Class of 2014, verbally committed to Stanford University on Saturday, bootleg.com reported. Simmons made visits to five schools in six days on the West Coast before telling Cardinal coach David Shaw of his intentions.
Simmons (6-0, 175) reportedly received offers from more than 40 colleges, including seven other Pac-12 schools. The junior at Timberview High School in Arlington, Texas is ranked among the top recruits at his position . . . Menlo School grad Ryan Cavan had two hits and raised his batting average to .382 while helping the San Jose Giants hold off the Stockton Ports, 2-1, Tuesday night at San Jose Municipal Stadium . . . Santa Clara University's Larry Jackson, the 2012 West Coast Conference Goalkeeper of the Year, is working out with the Colorado Rapids as its third goalkeeper the MLS team announced last week. "We are very excited for the opportunity that Larry has earned," said SCU goalkeeper coach Eric Yamamoto. "He is a great student of the game and is committed to improving every day. His consistent improvement and hunger to learn has gotten him to this point and we think that his best days are still ahead of him." Jackson, who hails from East Palo Alto, went undrafted following the MLS Combine in January.


text:
In the furniture world, High Point, North Carolina is the place to be in October. All the big, multi-national furniture wholesalers are there at the Annual Furniture Market selling to retailers from across America.
For the past 30-40 years these companies have been manufacturing their furniture in China, Vietnam and other third world countries. They moved there from places like North Carolina and Virginia in the 70s and 80s to take advantage of cheap labor, illegally harvested wood and lax safety and health regulations.
Well, now that wages and safety are both on the rise in China, the furniture companies are moving back to the USA. This year they are pushing two new over-arching sales themes at the High Point Market: American Made Furniture and Eco-Friendly, Green Furniture.
Hmmm. That sounds familiar, doesn't it? In Vermont our furniture makers have embodied these themes throughout our history. Vermont furniture has always been true to its American heritage, American quality and American jobs. And our states' furniture craftspeople have consistently used eco-friendly, sustainably harvested wood and non-toxic finishes for their work.
From the small custom shops that make one of a kind studio furniture to our medium and large scale furniture makers like Lyndon Furniture, Copeland Furniture, Pompanoosuc Mills, New England Woodcraft, Vermont Furniture Designs and Maple Corner Woodworks, Vermont craftsmen have been authentically American and eco-friendly throughout our history. It's not just a passing fad in Vermont and you can rest assured that we will be providing heirloom quality, natural, handmade furniture for generations to come.
Already following our Blog? For more info sign up for our e-newsletter
This blog is written by your friends at Vermont Woods Studios. Check out our Vermont made furniture and home decor online and visit our showroom and art gallery at Stonehurst, the newly restored 1800s farmhouse nestled in the foothills of the Green Mountains.


text: Personal Space LeAnn Rimes' Ex Dean Sheremet Talks Breakups in Our New Series! Host Greta Titelman welcomes Dean Sheremet, Dr. Roshini Raj, and Courtney Rada to talk about divorce, cyber stalking, and the physical effects of a broken heart. Watch Video Most Popular Jim Edmonds Shows His Softer (and Musical) Side with Shannon Beador Adrienne Maloof Has Gotten Back Together with One of Her Exes Beyoncé's Birthday Cake Was Sparkly and Outrageous Because... Beyoncé (PICS) Does Kate Chastain Still Keep in Touch with "Hot Jesus"? Top Shows Below Deck Odd Mom Out #RHOC #RHOD Shahs of Sunset #WWHL See All Shows On Tonight 8:00 pm Flipping Out 9:00 pm NEW Flipping Out 10:00 pm NEW Girlfriends Guide to Divorce 11:00 pm NEW Watch What Happens Live See Schedule Editor's Picks The Real Housewives of Atlanta The Real Housewives of Atlanta Your First Look at the New Season! Get ready to pop some bottles! Show Highlight Below Deck Do You Remember the Other Naked Sushi Incident on Bravo? Bruno Duarte really took one for the team this week by donning a skimpy ensemple and becoming a living tray of sushi for th Show Highlight Xscape: Still Kickin' It See the Ladies of Xscape Back in Action Eighteen years later, the fierce foursome known as Xscape are ready to make sweet music again... but not without some drama along the way. Show Highlight Married to Medicine Watch the #Married2Med Trailer Stat! It's on! Tensions are high for the ladies of Married to Medicine when Season 5 premieres on Bravo this November. Preview The Real Housewives Awards Who Are the Best Bravo BFFs? Vote for Your Fave Duo! Preview Trend Testers Can an Eyeliner Replace Your Favorite Eye Primer? Lately, the beauty world has gained a whole new fascination with skincare—and especially, with masks. Adrienne Maloof Has Gotten Back Together with One of Her Exes More Pop Culture Beyoncé's Birthday Cake Was Sparkly and Outrageous Because... Beyoncé (PICS) More Food Gordon Ramsay Refused to Swim in a Hotel Pool for This Very Nasty Reason More Travel Fergie Admits She And Josh Duhamel Were Pretending To Be Together - And It Got "Weird" More Relationships RHOC's Tamra Judge Has an Unexpected New Look More Fashion/Beauty Trending Videos Show Highlight 00:55 Watch What Happens Live with Andy Cohen Jax Taylor Shares Vanderpump News S14/EP148: Jax Taylor is asked what the cast of #PumpRules is up to these days, including if Jax is on good terms with James Kennedy and if Lala Kent is in good graces with the group. Preview 02:13 The Real Housewives of Atlanta Your First Look at Season 10 of #RHOA Some familiar faces have returned... Preview 02:04 Married to Medicine This Season on Married to Medicine... As doctors they're trained to fix almost any situation, but there's no amount of medicine that can fix these marriages. Preview 00:54 The Real Housewives of Orange County Next on RHOC: Peggy Is Feeling Tested by the Ladies S12/EP12: Peggy and Kelly go head to head at dinner. View all Listen to The Daily Dish Podcast You already spend your nights watching Bravo, so why not wake up with us, too? Watch Video Watch Full Episodes Watch Now Shop by Bravo Find the perfect gift for all the Bravo lovers in your life. Shop Now Join Our Viewer's Voice Panel Share your opinions and feedback on your favorite TV shows. Go Now Watch Bravo Live See your favorite shows online anytime. Watch Now


text:
|What are some ways Phoenix could develop to stand out from the crowd? (197 replies)
|What size do you see the Phoenix area growing into by 2050? (84 replies)
|Arizona Republic article "Phoenix is the nation's 5th largest � but is it a 'real' city?" (41 replies)
|For established Phoenix residents, does Phoenix offer a good quality of life? (68 replies)
|Phoenix Area Job Market (59 replies)
|Another Phoenix bus strike looming (Transdev-Phoenix North and South Divisions) (82 replies)


text:
Astros send Albers to DL, call up Cisnero
HOUSTON -- The Astros' offseason pitching acquisitions keep going down.
The organization announced Friday that reliever Matt Albers had been placed on the 15-day disabled list retroactive to April 22 because of tendinitis in his right shoulder. The righty joins veteran Scott Feldman on the DL. Jose Cisnero was called up from Triple-A Oklahoma City in Albers' place.
"He hadn't thrown in a few days, and in talking to the doctor and talking to Matt we felt like the best idea was to be cautious and give him as much time as possible," general manager Jeff Luhnow said. "We do have two off-days next week, so that gives us a little bit of comfort."
Albers had missed three straight games prior to Friday, but manager Bo Porter had said he hoped to avoid an official stint on the disabled list.
After Albers was evaluated by trainers and received treatment on the shoulder, that apparently was not possible.
"I'm a little concerned, yeah," Albers said. "Going on the DL, that's never a good feeling. Hopefully it's just some discomfort and inflammation and we deal with it early enough to not miss significant amount of time."
Albers, 31, had been the Astros' best bullpen arm this season, posting a sub-1.00 ERA and allowing only one run in 10 innings.
But as he was compiling those numbers, Albers said, his arm was only getting more tender with each outing.
"It's just gradually gotten worse," he said. "Just starts off with some soreness, no big deal, and progresses to the point where it'll continue to get worse unless I take some time off. It got to a point where it wasn't comfortable to pitch."
Cisnero struck out 18 hitters in 11 innings during six appearances with the Redhawks after showing some positives strides in Spring Training.
"He was off to a great start in Triple-A," Luhnow said. "He's been working on his secondary stuff, and it's coming along pretty well. He's also gotten up to 96 [miles per hour]. He can go one inning or he can pitch three innings, so it gives us some flexibility in the bullpen and a live arm.
"We're excited about his return."
Cisnero spent a couple of months in Houston last season, compiling a 2-2 record while surrendering 23 runs (20 earned) but fanning 41 batters in 43 2/3 innings.
"Last year for a good stretch he was arguably one of our better relievers, and he hit a snag where he really just lost his fastball command," Porter said. "He's worked extremely hard in getting the mechanics back, and we can't wait to get a look at him."
Chris Abshire is a contributor to MLB.com. This story was not subject to the approval of Major League Baseball or its clubs.


text:
12 Testing - Reference Documentation
Authors: Graeme Rocher, Peter Ledbrook, Marc Palmer, Jeff Brown, Luke Daley, Burt Beckwith
Version: 2.3.4
Table of Contents
12 TestingAutomated testing is a key part of Grails. Hence, Grails provides many ways to making testing easier from low level unit testing to high level functional tests. This section details the different capabilities that Grails offers for testing.
Grails 1.3.x and below used the The first thing to be aware of is that all of the
grails.test.GrailsUnitTestCase class hierarchy for testing in a JUnit 3 style. Grails 2.0.x and above deprecates these test harnesses in favour of mixins that can be applied to a range of different kinds of tests (JUnit 3, Junit 4, Spock etc.) without subclassing
create-* and
generate-* commands create
unit or
integration tests automatically. For example if you run the create-controller command as follows:
Grails will create a controller at
grails create-controller com.acme.app.simple
grails-app/controllers/com/acme/app/SimpleController.groovy, and also a unit test at
test/unit/com/acme/app/SimpleControllerTests.groovy. What Grails won't do however is populate the logic inside the test! That is left up to you.
The default class name suffix is
Testsbut as of Grails 1.2.2, the suffix of
Testis also supported.
Running TestsTests are run with the test-app command:
The command will produce output such as:
grails test-app
whilst showing the reason for each test failure.
------------------------------------------------------- Running Unit Tests… Running test FooTests...FAILURE Unit Tests Completed in 464ms … -------------------------------------------------------Tests failed: 0 errors, 1 failures
You can force a clean before running tests by passingGrails writes both plain text and HTML test reports to the
-cleanto the
target/test-reports directory, along with the original XML files. The HTML reports are generally the best ones to look at.Using Grails' interactive mode confers some distinct advantages when executing tests. First, the tests will execute significantly faster on the second and subsequent runs. Second, a shortcut is available to open the HTML reports in your browser:
You can also run your unit tests from within most IDEs.
open test-report
Targeting TestsYou can selectively target the test(s) to be run in different ways. To run all tests for a controller named
SimpleController you would run:
This will run any tests for the class named
grails test-app SimpleController
SimpleController. Wildcards can be used...
This will test all classes ending in
grails test-app *Controller
Controller. Package names can optionally be specified...
or to run all tests in a package...
grails test-app some.org.*Controller
or to run all tests in a package including subpackages...
grails test-app some.org.*
You can also target particular test methods...
grails test-app some.org.**.*
This will run the
grails test-app SimpleController.testLogin
testLogin test in the
SimpleController tests. You can specify as many patterns in combination as you like...
grails test-app some.org.* SimpleController.testLogin BookController
Targeting Test Types and/or PhasesIn addition to targeting certain tests, you can also target test types and/or phases by using the
phase:type syntax.
Grails organises tests by phase and by type. A test phase relates to the state of the Grails application during the tests, and the type relates to the testing mechanism.Grails comes with support for 4 test phases (To execute the JUnit
other) and JUnit test types for the
integrationphases. These test types have the same name as the phase.Testing plugins may provide new test phases or new test types for existing phases. Refer to the plugin documentation.
integration tests you can run:
grails test-app integration:integration
phase and
type are optional. Their absence acts as a wildcard. The following command will run all test types in the
unit phase:
The Grails Spock Plugin is one plugin that adds new test types to Grails. It adds a
grails test-app unit:
spock test type to the
integration and
functional phases. To run all spock tests in all phases you would run the following:
To run the all of the spock tests in the
grails test-app :spock
functional phase you would run...
More than one pattern can be specified...
grails test-app functional:spock
grails test-app unit:spock integration:spock
Targeting Tests in Types and/or PhasesTest and type/phase targetting can be applied at the same time:
This would run all tests in the
grails test-app integration: unit: some.org.**.*
integration and
unit phases that are in the package
some.org or a subpackage.
12.1 Unit TestingUnit testing are tests at the "unit" level. In other words you are testing individual methods or blocks of code without consideration for surrounding infrastructure. Unit tests are typically run without the presence of physical resources that involve I/O such databases, socket connections or files. This is to ensure they run as quick as possible since quick feedback is important.
The Test MixinsSince Grails 2.0, a collection of unit testing mixins is provided by Grails that lets you enhance the behavior of a typical JUnit 3, JUnit 4 or Spock test. The following sections cover the usage of these mixins.
The previous JUnit 3-style You won't normally have to import any of the testing classes because Grails does that for you. But if you find that your IDE for example can't find the classes, here they all are:
GrailsUnitTestCase class hierarchy is still present in Grails for backwards compatibility, but is now deprecated. The previous documentation on the subject can be found in the Grails 1.3.x documentation
Test Mixin BasicsMost testing can be achieved via the
TestFor annotation in combination with the
Mock annotation for mocking collaborators. For example, to test a controller and associated domains you would define the following:
@TestFor(BookController) @Mock([Book, Author, BookService])
TestFor annotation defines the class under test and will automatically create a field for the type of class under test. For example in the above case a "controller" field will be present, however if
TestFor was defined for a service a "service" field would be created and so on.The
Mock annotation creates mock version of any collaborators. There is an in-memory implementation of GORM that will simulate most interactions with the GORM API. For those interactions that are not automatically mocked you can use the built in support for defining mocks and stubs programmatically. For example:
void testSearch() { def control = mockFor(SearchService) control.demand.searchWeb { String q -> ['mock results'] } control.demand.static.logResults { List results -> } controller.searchService = control.createMock() controller.search() assert controller.response.text.contains "Found 1 results" }
12.1.1 Unit Testing Controllers
The BasicsYou use the
grails.test.mixin.TestFor annotation to unit test controllers. Using
TestFor in this manner activates the
grails.test.mixin.web.ControllerUnitTestMixin and its associated API. For example:
Adding the
import grails.test.mixin.TestFor@TestFor(SimpleController)
class SimpleControllerTests {
void testSomething() { }
TestFor annotation to a controller causes a new
controller field to be automatically created for the controller under test.
The To test the simplest "Hello World"-style example you can do the following:
TestFor annotation will also automatically annotate any public methods starting with "test" with JUnit 4's @Test annotation. If any of your test method don't start with "test" just add this manually
// Test class
class SimpleController {
def hello() {
render "hello"
void testHello() { controller.hello() assert response.text == 'hello' }
response object is an instance of
GrailsMockHttpServletResponse (from the package
org.codehaus.groovy.grails.plugins.testing) which extends Spring's
MockHttpServletResponse class and has a number of useful methods for inspecting the state of the response.For example to test a redirect you can use the
redirectedUrl property:
// Test class class SimpleController { def index() { redirect action: 'hello' } … }
Many actions make use of the parameter data associated with the request. For example, the 'sort', 'max', and 'offset' parameters are quite common. Providing these in the test is as simple as adding appropriate values to a special
void testIndex() { controller.index() assert response.redirectedUrl == '/simple/hello' }
params variable:
You can even control what type of request the controller action sees by setting the
void testList() {
params.sort = "name"
params.max = 20
params.offset = 0 controller.list()
method property of the mock request:
This is particularly important if your actions do different things depending on the type of the request. Finally, you can mark a request as AJAX like so:
void testSave() {
request.method = "POST"
You only need to do this though if the code under test uses the
void testGetPage() {
request.method = "POST"
xhr property on the request.
Testing View RenderingTo test view rendering you can inspect the state of the controller's
modelAndView property (an instance of
org.springframework.web.servlet.ModelAndView) or you can use the
view and
model properties provided by the mixin:
// Test class class SimpleController { def home() { render view: "homePage", model: [title: "Hello World"] } … }
Note that the view string is the absolute view path, so it starts with a '/' and will include path elements, such as the directory named after the action's controller.
void testIndex() { controller.home() assert view == "/simple/homePage" assert model.title == "Hello World" }
Testing Template RenderingUnlike view rendering, template rendering will actually attempt to write the template directly to the response rather than returning a
ModelAndView hence it requires a different approach to testing.Consider the following controller action:
In this example the controller will look for a template in
class SimpleController {
def display() {
render template:"snippet"
grails-app/views/simple/_snippet.gsp. You can test this as follows:
However, you may not want to render the real template, but just test that is was rendered. In this case you can provide mock Groovy Pages:
void testDisplay() { controller.display() assert response.text == 'contents of template' }
void testDisplay() { views['/simple/_snippet.gsp'] = 'mock contents' controller.display() assert response.text == 'mock contents' }
Testing Actions Which Return A MapWhen a controller action returns a
java.util.Map that
Map may be inspected directly to assert that it contains the expected data:
class SimpleController { def showBookDetails() { [title: 'The Nature Of Necessity', author: 'Alvin Plantinga'] } }
import grails.test.mixin.*@TestFor(SimpleController)
class SimpleControllerTests { void testShowBookDetails() {
def model = controller.showBookDetails() assert model.author == 'Alvin Plantinga'
Testing XML and JSON ResponsesXML and JSON response are also written directly to the response. Grails' mocking capabilities provide some conveniences for testing XML and JSON response. For example consider the following action:
This can be tested using the
def renderXml() { render(contentType:"text/xml") { book(title:"Great") } }
xml property of the response:
void testRenderXml() { controller.renderXml() assert "<book title='Great'/>" == response.text assert "Great" == [email protected]() }
xml property is a parsed result from Groovy's XmlSlurper class which is very convenient for parsing XML.Testing JSON responses is pretty similar, instead you use the
json property:
// controller action def renderJson() { render(contentType:"application/json") { book = "Great" } }
// test void testRenderJson() { controller.renderJson() assert '{"book":"Great"}' == response.text assert "Great" == response.json.book }
json property is an instance of
org.codehaus.groovy.grails.web.json.JSONElement which is a map-like structure that is useful for parsing JSON responses.
Testing XML and JSON RequestsGrails provides various convenient ways to automatically parse incoming XML and JSON packets. For example you can bind incoming JSON or XML requests using Grails' data binding:
To test this Grails provides an easy way to specify an XML or JSON packet via the
def consumeBook() {
def b = new Book(params['book']) render b.title
xml or
json properties. For example the above action can be tested by specifying a String containing the XML:
Or alternatively a domain instance can be specified and it will be auto-converted into the appropriate XML request:
void testConsumeBookXml() { request.xml = '<book><title>The Shining</title></book>' controller.consumeBook() assert response.text == 'The Shining' }
The same can be done for JSON requests:
void testConsumeBookXml() { request.xml = new Book(title:"The Shining") controller.consumeBook() assert response.text == 'The Shining' }
If you prefer not to use Grails' data binding but instead manually parse the incoming XML or JSON that can be tested too. For example consider the controller action below:
void testConsumeBookJson() { request.json = new Book(title:"The Shining") controller.consumeBook() assert response.text == 'The Shining' }
To test the XML request you can specify the XML as a string:
def consume() { request.withFormat { xml { render [email protected] } json { render request.JSON.title } } }
And, of course, the same can be done for JSON:
void testConsumeXml() {
request.xml = '<book title="The Stand" />' controller.consume() assert response.text == 'The Stand'
void testConsumeJson() {
request.json = '{title:"The Stand"}'
controller.consume() assert response.text == 'The Stand'
Testing Spring BeansWhen using
TestFor only a subset of the Spring beans available to a running Grails application are available. If you wish to make additional beans available you can do so with the
defineBeans method of
class SimpleController { SimpleService simpleService def hello() { render simpleService.sayHello() } }
The controller is auto-wired by Spring just like in a running Grails application. Autowiring even occurs if you instantiate subsequent instances of the controller:
void testBeanWiring() {
defineBeans {
} controller.hello() assert response.text == "Hello World"
void testAutowiringViaNew() { defineBeans { simpleService(SimpleService) } def controller1 = new SimpleController() def controller2 = new SimpleController() assert controller1.simpleService != null assert controller2.simpleService != null }
Testing Mime Type HandlingYou can test mime type handling and the
withFormat method quite simply by setting the response's
format attribute:
// controller action
def sayHello() {
def data = [Hello:"World"]
withFormat {
xml { render data as XML }
html data
// test void testSayHello() { response.format = 'xml' controller.sayHello() String expected = '<?xml version="1.0" encoding="UTF-8"?>' + '<map><entry key="Hello">World</entry></map>' assert expected == response.text }
Testing Duplicate Form SubmissionsTesting duplicate form submissions is a little bit more involved. For example if you have an action that handles a form such as:
you want to verify the logic that is executed on a good form submission and the logic that is executed on a duplicate submission. Testing the bad submission is simple. Just invoke the controller:
def handleForm() { withForm { render "Good" }.invalidToken { render "Bad" } }
Testing the successful submission requires providing an appropriate
void testDuplicateFormSubmission() {
assert "Bad" == response.text
If you test both the valid and the invalid request in the same test be sure to reset the response between executions of the controller:
import org.codehaus.groovy.grails.web.servlet.mvc.SynchronizerToken ...void testValidFormSubmission() { def tokenHolder = SynchronizerTokensHolder.store(session) params[SynchronizerTokensHolder.TOKEN_URI] = '/controller/handleForm' params[SynchronizerTokensHolder.TOKEN_KEY] = tokenHolder.generateToken(params[SynchronizerTokensHolder.TOKEN_URI]) controller.handleForm() assert "Good" == response.text }
controller.handleForm() // first execution … response.reset() … controller.handleForm() // second execution
Testing File UploadYou use the
GrailsMockMultipartFile class to test file uploads. For example consider the following controller action:
To test this action you can register a
def uploadFile() { MultipartFile file = request.getFile("myFile") file.transferTo(new File("/local/disk/myFile")) }
GrailsMockMultipartFile with the request:
void testFileUpload() { final file = new GrailsMockMultipartFile("myFile", "foo".bytes) request.addFile(file) controller.uploadFile() assert file.targetFileLocation.path == "/local/disk/myFile" }
GrailsMockMultipartFile constructor arguments are the name and contents of the file. It has a mock implementation of the
transferTo method that simply records the
targetFileLocation and doesn't write to disk.
Testing Command ObjectsSpecial support exists for testing command object handling with the
mockCommandObject method. For example consider the following action:
To test this you mock the command object, populate it and then validate it as follows:
def handleCommand(SimpleCommand simple) { if (simple.hasErrors()) { render "Bad" } else { render "Good" } }
void testInvalidCommand() { def cmd = mockCommandObject(SimpleCommand) cmd.name = '' // doesn't allow blank names cmd.validate() controller.handleCommand(cmd) assert response.text == 'Bad' }
Testing Calling Tag LibrariesYou can test calling tag libraries using
ControllerUnitTestMixin, although the mechanism for testing the tag called varies from tag to tag. For example to test a call to the
message tag, add a message to the
messageSource. Consider the following action:
This can be tested as follows:
def showMessage() {
render g.message(code: "foo.bar")
void testRenderBasicTemplateWithTags() { messageSource.addMessage("foo.bar", request.locale, "Hello World") controller.showMessage() assert response.text == "Hello World" }
12.1.2 Unit Testing Tag Libraries
The BasicsTag libraries and GSP pages can be tested with the
grails.test.mixin.web.GroovyPageUnitTestMixin mixin. To use the mixin declare which tag library is under test with the
TestFor annotation:
Note that if you are testing invocation of a custom tag from a controller you can combine the
@TestFor(SimpleTagLib) class SimpleTagLibTests {}
ControllerUnitTestMixin and the
GroovyPageUnitTestMixin using the
Mock annotation:
@TestFor(SimpleController) @Mock(SimpleTagLib) class GroovyPageUnitTestMixinTests {}
Testing Custom TagsThe core Grails tags don't need to be enabled during testing, however custom tag libraries do. The
GroovyPageUnitTestMixin class provides a
mockTagLib() method that you can use to mock a custom tag library. For example consider the following tag library:
You can test this tag library by using
class SimpleTagLib { static namespace = 's' def hello = { attrs, body -> out << "Hello ${attrs.name ?: 'World'}" } def bye = { attrs, body -> out << "Bye ${attrs.author.name ?: 'World'}" } }
TestFor and supplying the name of the tag library:
Alternatively, you can use the
@TestFor(SimpleTagLib) class SimpleTagLibTests { void testHelloTag() { assert applyTemplate('<s:hello />') == 'Hello World' assert applyTemplate('<s:hello name="Fred" />') == 'Hello Fred' assert applyTemplate('<s:bye author="${author}" />', [author: new Author(name: 'Fred')]) == 'Bye Fred' } }
TestMixin annotation and mock multiple tag libraries using the
mockTagLib() method:
@grails.test.mixin.TestMixin(GroovyPageUnitTestMixin) class MultipleTagLibraryTests { @Test void testMuliple() { mockTagLib(FirstTagLib) mockTagLib(SecondTagLib) … } }
GroovyPageUnitTestMixin provides convenience methods for asserting that the template output equals or matches an expected value.
class MultipleTagLibraryTests { @Test
void testMuliple() {
assertOutputEquals ('Hello World', '<s:hello />')
assertOutputMatches (/.*Fred.*/, '<s:hello name="Fred" />')
Testing View and Template RenderingYou can test rendering of views and templates in
grails-app/views via the
render(Map) method provided by
GroovyPageUnitTestMixin :
This will attempt to render a template found at the location
def result = render(template: "/simple/hello") assert result == "Hello World"
grails-app/views/simple/_hello.gsp. Note that if the template depends on any custom tag libraries you need to call
mockTagLib as described in the previous section.
12.1.3 Unit Testing Domains
The mocking support described here is best used when testing non-domain artifacts that use domain classes, to let you focus on testing the artifact without needing a database. But when testing persistence it's best to use integration tests which configure Hibernate and use a database.Domain class interaction can be tested without involving a database connection using
DomainClassUnitTestMixin. This implementation mimics the behavior of GORM against an in-memory
ConcurrentHashMap implementation. Note that this has limitations compared to a real GORM implementation. The following features of GORM for Hibernate can only be tested within an integration test:
- String-based HQL queries
- composite identifiers
- dirty checking methods
- any direct interaction with Hibernate
DomainClassUnitTestMixin including:
- Simple persistence methods like
- Dynamic Finders
- Named Queries
- Query-by-example
- GORM Events
mockFor method can come in handy to mock the missing pieces. Alternatively you can write an integration test which bootstraps the complete Grails environment at a cost of test execution time.
The Basics
DomainClassUnitTestMixin is typically used in combination with testing either a controller, service or tag library where the domain is a mock collaborator defined by the
Mock annotation:
The example above tests the
import grails.test.mixin.*@TestFor(SimpleController)
class SimpleControllerTests {}
SimpleController class and mocks the behavior of the
Simple domain class as well. For example consider a typical scaffolded
save controller action:
Tests for this action can be written as follows:
class BookController { def save() { def book = new Book(params) if (book.save(flush: true)) { flash.message = message( code: 'default.created.message', args: [message(code: 'book.label', default: 'Book'), book.id])}" redirect(action: "show", id: book.id) } else { render(view: "create", model: [bookInstance: book]) } } }
import grails.test.mixin.*@TestFor(BookController) @Mock(Book) class BookControllerTests { void testSaveInvalidBook() { controller.save() assert model.bookInstance != null assert view == '/book/create' } void testSaveValidBook() { params.title = "The Stand" params.pages = "500" controller.save() assert response.redirectedUrl == '/book/show/1' assert flash.message != null assert Book.count() == 1 } }
Mock annotation also supports a list of mock collaborators if you have more than one domain to mock:
Alternatively you can also use the
@TestFor(BookController) @Mock([Book, Author]) class BookControllerTests { … }
DomainClassUnitTestMixin directly with the
TestMixin annotation:
And then call the
import grails.test.mixin.domain.DomainClassUnitTestMixin@TestFor(BookController)
class BookControllerTests {
mockDomain method to mock domains during your test:
void testSave() { mockDomain(Author) mockDomain(Book) }
mockDomain method also includes an additional parameter that lets you pass a Map of Maps to configure a domain, which is useful for fixture-like data:
void testSave() { mockDomain(Book, [ [title: "The Stand", pages: 1000], [title: "The Shining", pages: 400], [title: "Along Came a Spider", pages: 300] ]) }
Testing ConstraintsThere are 4 types of validateable classes:
- Domain classes
- Classes marked with the
- Command Objects which have been made validateable automatically
- Classes configured to be validateable via the
grails.validateable.classesproperty in
TestFor or explicitly applies the
GrailsUnitTestMixin using
TestMixin. See the examples below.
// src/groovy/com/demo/MyValidateable.groovy package email@example.com class MyValidateable { String name Integer age static constraints = { name matches: /[A-Z].*/ age range: 1..99 } }
// grails-app/domain/com/demo/Person.groovy package com.democlass Person { String name static constraints = { name matches: /[A-Z].*/ } }
// grails-app/controllers/com/demo/DemoController.groovy package com.democlass DemoController { def addItems(MyCommandObject co) { if(co.hasErrors()) { render 'something went wrong' } else { render 'items have been added' } } }class MyCommandObject { Integer numberOfItems static constraints = { numberOfItems range: 1..10 } }
// test/unit/com/demo/PersonSpec.groovy package com.demoimport grails.test.mixin.TestFor import spock.lang.Specification@TestFor(Person) class PersonSpec extends Specification { void "Test that name must begin with an upper case letter"() { when: 'the name begins with a lower letter' def p = new Person(name: 'jeff') then: 'validation should fail' !p.validate() when: 'the name begins with an upper case letter' p = new Person(name: 'Jeff') then: 'validation should pass' p.validate() } }
// test/unit/com/demo/DemoControllerSpec.groovy package com.demoimport grails.test.mixin.TestFor import spock.lang.Specification@TestFor(DemoController) class DemoControllerSpec extends Specification { void 'Test an invalid number of items'() { when: params.numberOfItems = 42 controller.addItems() then: response.text == 'something went wrong' } void 'Test a valid number of items'() { when: params.numberOfItems = 8 controller.addItems() then: response.text == 'items have been added' } }
// test/unit/com/demo/MyValidateableSpec.groovy package com.demoimport grails.test.mixin.TestMixin import grails.test.mixin.support.GrailsUnitTestMixin import spock.lang.Specification @TestMixin(GrailsUnitTestMixin) class MyValidateableSpec extends Specification { void 'Test validate can be invoked in a unit test with no special configuration'() { when: 'an object is valid' def validateable = new MyValidateable(name: 'Kirk', age: 47) then: 'validate() returns true and there are no errors' validateable.validate() !validateable.hasErrors() validateable.errors.errorCount == 0 when: 'an object is invalid' validateable.name = 'kirk' then: 'validate() returns false and the appropriate error is created' !validateable.validate() validateable.hasErrors() validateable.errors.errorCount == 1 validateable.errors['name'].code == 'matches.invalid' when: 'the clearErrors() is called' validateable.clearErrors() then: 'the errors are gone' !validateable.hasErrors() validateable.errors.errorCount == 0 when: 'the object is put back in a valid state' validateable.name = 'Kirk' then: 'validate() returns true and there are no errors' validateable.validate() !validateable.hasErrors() validateable.errors.errorCount == 0 } }
For validateable classes which are not one of the first 3 types listed above but are configured with the
// test/unit/com/demo/MyCommandObjectSpec.groovy package com.demoimport grails.test.mixin.TestMixin import grails.test.mixin.support.GrailsUnitTestMixin import spock.lang.Specification@TestMixin(GrailsUnitTestMixin) class MyCommandObjectSpec extends Specification { void 'Test that numberOfItems must be between 1 and 10'() { when: 'numberOfItems is less than 1' def co = new MyCommandObject() co.numberOfItems = 0 then: 'validation fails' !co.validate() co.hasErrors() co.errors['numberOfItems'].code == 'range.toosmall' when: 'numberOfItems is greater than 10' co.numberOfItems = 11 then: 'validation fails' !co.validate() co.hasErrors() co.errors['numberOfItems'].code == 'range.toobig' when: 'numberOfItems is greater than 1' co.numberOfItems = 1 then: 'validation succeeds' co.validate() !co.hasErrors() when: 'numberOfItems is greater than 10' co.numberOfItems = 10 then: 'validation succeeds' co.validate() !co.hasErrors() } }
grails.validateable.classes property in
Config.groovy, one additional step is required to test validation.
GrailsUnitTestMixin provides a method named
mockForConstraintsTests that will mock validation support for these classes. See the example below.
// src/groovy/com/demo/Book.groovy package com.democlass Book { String title String author static constraints = { author minSize: 5 } }
// grails-app/conf/Config.groovy grails.validateable.classes = [com.demo.Book]// ...
Note that the
// test/unit/com/demo/BookSpec.groovy package com.demoimport grails.test.mixin.TestMixin import grails.test.mixin.support.GrailsUnitTestMixin import spock.lang.Specification@TestMixin(GrailsUnitTestMixin) class BookSpec extends Specification { void 'Test validation'() { given: mockForConstraintsTests Book when: 'the author name has only 4 characters' def book = new Book() book.author = 'Jeff' then: 'validation should fail' !book.validate() book.hasErrors() book.errors['author'] == 'minSize' when: 'the author name has 5 characters' book.author = 'Jacob' then: 'validation should pass' book.validate() !book.hasErrors() } }
mockForConstraintsTests method changes the behavior of the errors object such that something like
book.errors'author' will evaluate to the name of the failed constraint, not a
org.springframework.validation.FieldError object. This is convenient for unit tests. If your unit test really does want a reference to the
org.springframework.validation.FieldError object use something like
book.errors.getFieldError('author').That's it for testing constraints. One final thing we would like to say is that testing the constraints in this way catches a common error: typos in the "constraints" property name which is a mistake that is easy to make and equally easy to overlook. A unit test for your constraints will highlight the problem straight away.
12.1.4 Unit Testing FiltersUnit testing filters is typically a matter of testing a controller where a filter is a mock collaborator. For example consider the following filters class:
This filter interceptors the
class CancellingFilters { def filters = { all(controller:"simple", action:"list") { before = { redirect(controller:"book") return false } } } }
list action of the
simple controller and redirects to the
book controller. To test this filter you start off with a test that targets the
SimpleController class and add the
CancellingFilters as a mock collaborator:
You can then implement a test that uses the
@TestFor(SimpleController) @Mock(CancellingFilters) class SimpleControllerTests {}
withFilters method to wrap the call to an action in filter execution:
Note that the
void testInvocationOfListActionIsFiltered() {
withFilters(action:"list") {
assert response.redirectedUrl == '/book'
action parameter is required because it is unknown what the action to invoke is until the action is actually called. The
controller parameter is optional and taken from the controller under test. If it is another controller you are testing then you can specify it:
withFilters(controller:"book",action:"list") { controller.list() }
12.1.5 Unit Testing URL Mappings
The BasicsTesting URL mappings can be done with the
TestFor annotation testing a particular URL mappings class. For example to test the default URL mappings you can do the following:
As you can see, any controller that is the target of a URL mapping that you're testing must be added to the
import org.example.AuthorController import org.example.SimpleController@TestFor(UrlMappings) @Mock([AuthorController, SimpleController]) class UrlMappingsTests { … }
@Mock annotation.
Note that since the default With that done there are a number of useful methods that are defined by the
UrlMappings class is in the default package your test must also be in the default package
grails.test.mixin.web.UrlMappingsUnitTestMixin for testing URL mappings. These include:
assertForwardUrlMapping- Asserts a URL mapping is forwarded for the given controller class (note that controller will need to be defined as a mock collaborate for this to work)
assertReverseUrlMapping- Asserts that the given URL is produced when reverse mapping a link to a given controller and action
assertUrlMapping- Asserts a URL mapping is valid for the given URL. This combines the
Asserting Forward URL MappingsYou use
assertForwardUrlMapping to assert that a given URL maps to a given controller. For example, consider the following URL mappings:
The following test can be written to assert these URL mappings:
static mappings = { "/action1"(controller: "simple", action: "action1") "/action2"(controller: "simple", action: "action2") }
void testUrlMappings() { assertForwardUrlMapping("/action1", controller: 'simple', action: "action1") assertForwardUrlMapping("/action2", controller: 'simple', action: "action2") shouldFail { assertForwardUrlMapping("/action2", controller: 'simple', action: "action1") } }
Assert Reverse URL MappingsYou use
assertReverseUrlMapping to check that correct links are produced for your URL mapping when using the
link tag in GSP views. An example test is largely identical to the previous listing except you use
assertReverseUrlMapping instead of
assertForwardUrlMapping. Note that you can combine these 2 assertions with
Simulating Controller MappingIn addition to the assertions to check the validity of URL mappings you can also simulate mapping to a controller by using your
UrlMappings as a mock collaborator and the
mapURI method. For example:
@TestFor(SimpleController) @Mock(UrlMappings) class SimpleControllerTests { void testControllerMapping() { SimpleController controller = mapURI('/simple/list') assert controller != null def model = controller.list() assert model != null } }
12.1.6 Mocking CollaboratorsBeyond the specific targeted mocking APIs there is also an all-purpose
mockFor() method that is available when using the
TestFor annotation. The signature of
mockFor is:
This is general-purpose mocking that lets you set up either strict or loose demands on a class.This method is surprisingly intuitive to use. By default it will create a strict mock control object (one for which the order in which methods are called is important) that you can use to specify demands:
mockFor(class, loose = false)
Notice that you can mock static as well as instance methods by using the "static" property. You then specify the name of the method to mock, with an optional range argument. This range determines how many times you expect the method to be called, and if the number of invocations falls outside of that range (either too few or too many) then an assertion error will be thrown. If no range is specified, a default of "1..1" is assumed, i.e. that the method must be called exactly once.The last part of a demand is a closure representing the implementation of the mock method. The closure arguments must match the number and types of the mocked method, but otherwise you are free to add whatever you want in the body.Call
def strictControl = mockFor(MyService) strictControl.demand.someMethod(0..2) { String arg1, int arg2 -> … } strictControl.demand.static.aStaticMethod {-> … }
mockControl.createMock() to get an actual mock instance of the class that you are mocking. You can call this multiple times to create as many mock instances as you need. And once you have executed the test method, call
mockControl.verify() to check that the expected methods were called.Grails mocks also provide a
demandExplicit method that can be used in place of demand. This will check the mocked class's metaClass and throw an ExplicitDemandException if a method with that name and signature doesn't exist. For example, given the service:
The following mocking works the same as demand
class MyService {
def someMethod(String s) { … }
While this mocking throws an ExplicitDemandException when the test is run.
def strictControl = mockFor(MyService)
//Works just like the demand method since method signature exists on the class
strictControl.demandExplicit.someMethod(1) { String arg1 }
Using demandExplicit should be the preferred method for mocking as it is more likely to catch issues when changing method signatures. Use demand when the method to be mocked is added dynamically, otherwise use demandExplicit.Lastly, the call:
def strictControl = mockFor(MyService) //Throws ExplicitDemandException because method signature doesn't exist strictControl.demandExplicit.someMethod(1) { String arg1, String arg2 }
will create a mock control object that has only loose expectations, i.e. the order that methods are invoked does not matter.
def looseControl = mockFor(MyService, true)
12.1.7 Mocking CodecsThe
GrailsUnitTestMixin provides a
mockCodec method for mocking custom codecs which may be invoked while a unit test is running.
Failing to mock a codec which is invoked while a unit test is running may result in a MissingMethodException.
12.2 Integration TestingIntegration tests differ from unit tests in that you have full access to the Grails environment within the test. Grails uses an in-memory H2 database for integration tests and clears out all the data from the database between tests.One thing to bear in mind is that logging is enabled for your application classes, but it is different from logging in tests. So if you have something like this:
the "starting tests" message is logged using a different system than the one used by the application. The
class MyServiceTests extends GroovyTestCase { void testSomething() { log.info "Starting tests" … } }
log property in the example above is an instance of
java.util.logging.Logger (inherited from the base class, not injected by Grails), which doesn't have the same methods as the
log property injected into your application artifacts. For example, it doesn't have
debug() or
trace() methods, and the equivalent of
warn() is in fact
TransactionsIntegration tests run inside a database transaction by default, which is rolled back at the end of the each test. This means that data saved during a test is not persisted to the database. Add a
transactional property to your test class to check transactional behaviour:
Be sure to remove any persisted data from a non-transactional test, for example in the
class MyServiceTests extends GroovyTestCase { static transactional = false void testMyTransactionalServiceMethod() { … } }
tearDown method, so these tests don't interfere with standard transactional tests that expect a clean database.
Testing ControllersTo test controllers you first have to understand the Spring Mock Library.Grails automatically configures each test with a MockHttpServletRequest, MockHttpServletResponse, and MockHttpSession that you can use in your tests. For example consider the following controller:
The tests for this would be:
class FooController { def text() { render "bar" } def someRedirect() { redirect(action:"bar") } }
In the above case
class FooControllerTests extends GroovyTestCase { void testText() { def fc = new FooController() fc.text() assertEquals "bar", fc.response.contentAsString } void testSomeRedirect() { def fc = new FooController() fc.someRedirect() assertEquals "/foo/bar", fc.response.redirectedUrl } }
response is an instance of
MockHttpServletResponse which we can use to obtain the generated content with
contentAsString (when writing to the response) or the redirected URL. These mocked versions of the Servlet API are completely mutable (unlike the real versions) and hence you can set properties on the request such as the
contextPath and so on.Grails does not invoke interceptors or servlet filters when calling actions during integration testing. You should test interceptors and filters in isolation, using functional testing if necessary.
Testing Controllers with ServicesIf your controller references a service (or other Spring beans), you have to explicitly initialise the service from your test.Given a controller using a service:
The test for this would be:
class FilmStarsController {
def popularityService def update() {
// do something with popularityService
class FilmStarsTests extends GroovyTestCase { def popularityService void testInjectedServiceInController () { def fsc = new FilmStarsController() fsc.popularityService = popularityService fsc.update() } }
Testing Controller Command ObjectsWith command objects you just supply parameters to the request and it will automatically do the command object work for you when you call your action with no parameters:Given a controller using a command object:
You can then test it like this:
class AuthenticationController { def signup(SignupForm form) { … } }
Grails auto-magically sees your call to
def controller = new AuthenticationController() controller.params.login = "marcpalmer" controller.params.password = "secret" controller.params.passwordConfirm = "secret" controller.signup()
signup() as a call to the action and populates the command object from the mocked request parameters. During controller testing, the
params are mutable with a mocked request supplied by Grails.
Testing Controllers and the render MethodThe render method lets you render a custom view at any point within the body of an action. For instance, consider the example below:
In the above example the result of the model of the action is not available as the return value, but instead is stored within the
def save() { def book = Book(params) if (book.save()) { // handle } else { render(view:"create", model:[book:book]) } }
modelAndView property of the controller. The
modelAndView property is an instance of Spring MVC's ModelAndView class and you can use it to the test the result of an action:
def bookController = new BookController()
def model = bookController.modelAndView.model.book
Simulating Request DataYou can use the Spring MockHttpServletRequest to test an action that requires request data, for example a REST web service. For example consider this action which performs data binding from an incoming request:
To simulate the 'book' parameter as an XML request you could do something like the following:
def create() {
[book: new Book(params.book)]
The same can be achieved with a JSON request:
void testCreateWithXML() { def controller = new BookController() controller.request.contentType = 'text/xml' controller.request.content = '''\ <?xml version="1.0" encoding="ISO-8859-1"?> <book> <title>The Stand</title> … </book> '''.stripIndent().getBytes() // note we need the bytes def model = controller.create() assert model.book assertEquals "The Stand", model.book.title }
void testCreateWithJSON() { def controller = new BookController() controller.request.contentType = "application/json" controller.request.content = '{"id":1,"class":"Book","title":"The Stand"}'.getBytes() def model = controller.create() assert model.book assertEquals "The Stand", model.book.title }
With JSON don't forget theFor more information on the subject of REST web services see the section on REST.
classproperty to specify the name the target type to bind to. In XML this is implicit within the name of the
<book>node, but this property is required as part of the JSON packet.
Testing Web FlowsTesting Web Flows requires a special test harness called
grails.test.WebFlowTestCase which subclasses Spring Web Flow's AbstractFlowExecutionTests class.
Subclasses of For example given this simple flow:
WebFlowTestCase must be integration tests
You need to tell the test harness what to use for the "flow definition". This is done via overriding the abstract
class ExampleController { def exampleFlow() { start { on("go") { flow.hello = "world" }.to "next" } next { on("back").to "start" on("go").to "subber" } subber { subflow(action: "sub") on("end").to("end") } end() } def subFlow() { subSubflowState { subflow(controller: "other", action: "otherSub") on("next").to("next") } … } }
You can specify the flow id by overriding the
import grails.test.WebFlowTestCaseclass ExampleFlowTests extends WebFlowTestCase { def getFlow() { new ExampleController().exampleFlow } … }
getFlowId method, otherwise the default is
If the flow under test calls any subflows, these (or mocks) must be registered before the calling the flow:
import grails.test.WebFlowTestCaseclass ExampleFlowTests extends WebFlowTestCase { String getFlowId() { "example" } … }
Then you kick off the flow with the
protected void setUp() { super.setUp() registerFlow("other/otherSub") { // register a simplified mock start { on("next").to("end") } end() } // register the original subflow registerFlow("example/sub", new ExampleController().subFlow) }
startFlow method:
Use the
void testExampleFlow() { def viewSelection = startFlow() … }
signalEvent method to trigger an event:
Here we have signaled to the flow to execute the event "go" which causes a transition to the "next" state. In the example a transition action placed a
void testExampleFlow() { … signalEvent("go") assert "next" == flowExecution.activeSession.state.id assert "world" == flowScope.hello }
hello variable into the flow scope.
Testing Tag LibrariesTesting tag libraries is simple because when a tag is invoked as a method it returns its result as a string (technically a
StreamCharBuffer but this class implements all of the methods of
String). So for example if you have a tag library like this:
The tests would look like:
class FooTagLib { def bar = { attrs, body -> out << "<p>Hello World!</p>" } def bodyTag = { attrs, body -> out << "<${attrs.name}>" out << body() out << "</${attrs.name}>" } }
Notice that for the second example,
class FooTagLibTests extends GroovyTestCase { void testBarTag() { assertEquals "<p>Hello World!</p>", new FooTagLib().bar(null, null).toString() } void testBodyTag() { assertEquals "<p>Hello World!</p>", new FooTagLib().bodyTag(name: "p") { "Hello World!" }.toString() } }
testBodyTag, we pass a block that returns the body of the tag. This is convenient to representing the body as a String.
Testing Tag Libraries with GroovyPagesTestCaseIn addition to doing simple testing of tag libraries like in the above examples, you can also use the
grails.test.GroovyPagesTestCase class to test tag libraries with integration tests.The
GroovyPagesTestCase class is a subclass of the standard
GroovyTestCase class and adds utility methods for testing the output of GSP rendering.
For example, consider this date formatting tag library:
GroovyPagesTestCase can only be used in an integration test.
This can be easily tested as follows:
import java.text.SimpleDateFormatclass FormatTagLib { def dateFormat = { attrs, body -> out << new SimpleDateFormat(attrs.format) << attrs.date } }
You can also obtain the result of a GSP using the
class FormatTagLibTests extends GroovyPagesTestCase { void testDateFormat() { def template = '<g:dateFormat format="dd-MM-yyyy" date="${myDate}" />' def testDate = … // create the date assertOutputEquals('01-01-2008', template, [myDate:testDate]) } }
applyTemplate method of the
GroovyPagesTestCase class:
class FormatTagLibTests extends GroovyPagesTestCase { void testDateFormat() { def template = '<g:dateFormat format="dd-MM-yyyy" date="${myDate}" />' def testDate = … // create the date def result = applyTemplate(template, [myDate:testDate]) assertEquals '01-01-2008', result } }
Testing Domain ClassesTesting domain classes is typically a simple matter of using the GORM API, but there are a few things to be aware of. Firstly, when testing queries you often need to "flush" to ensure the correct state has been persisted to the database. For example take the following example:
This test will fail because calling save does not actually persist the
void testQuery() { def books = [ new Book(title: "The Stand"), new Book(title: "The Shining")] books*.save() assertEquals 2, Book.list().size() }
Book instances when called. Calling
save only indicates to Hibernate that at some point in the future these instances should be persisted. To commit changes immediately you "flush" them:
In this case since we're passing the argument
void testQuery() { def books = [ new Book(title: "The Stand"), new Book(title: "The Shining")] books*.save(flush: true) assertEquals 2, Book.list().size() }
flush with a value of
true the updates will be persisted immediately and hence will be available to the query later on.
12.3 Functional TestingFunctional tests involve making HTTP requests against the running application and verifying the resultant behaviour. The functional testing phase differs from the integration phase in that the Grails application is now listening and responding to actual HTTP requests. This is useful for end-to-end testing scenarios, such as making REST calls against a JSON API.Grails does not ship with any support for writing functional tests directly, but there are several plugins available for this.
Canoo Webtest- http://grails.org/plugin/webtest
G-Func- http://grails.org/plugin/functional-test
Geb- http://grails.org/plugin/geb
Selenium-RC- http://grails.org/plugin/selenium-rc
WebDriver- http://grails.org/plugin/webdriver
Common OptionsThere are options that are common to all plugins that control how the Grails application is launched, if at all.
-inline option specifies that the grails application should be started inline (i.e. like
run-app).This option is implicitly set unless the
baseUrl or
war options are set
-war option specifies that the grails application should be packaged as a war and started. This is useful as it tests your application in a production-like state, but it has a longer startup time than the
-inline option. It also runs the war in a forked JVM, meaning that you cannot access any internal application objects.
Note that the same build/config options for the run-war command apply to functional testing against the WAR.
grails test-app functional: -war
-https option results in the application being able to receive https requests as well as http requests. It is compatible with both the
-inline and
-war options.
Note that this does not change the test base url to be https, it will still be http unless the
grails test-app functional: -https
-httpsBaseUrl option is also given.
-httpsBaseUrl causes the implicit base url to be used for tests to be a https url.
This option is ignored if the
grails test-app functional: -httpsBaseUrl
-baseUrl option is specified.
baseUrl option allows the base url for tests to be specified.
This option will prevent the local grails application being started unless
grails test-app functional: -baseUrl=http://mycompany.com/grailsapp
-inline or
-war are given as well. To use a custom base url but still test against the local Grails application you must specify one of either the
-inline or
-war options.


text:
Redondo Beach, CA, US
As Project and Design Manager for general contractor, I am responsible for domestic and international public sector design/build projects. Types include those for higher education, and agencies representing a complete spectrum of municipal clients. Current projects include facilities on three Los Angeles Community College (LACCD) campuses with a total value of over $100 million. In this capacity I manage architects and engineers providing proactive project leadership to facilitate delivery of award-winning, LEED accredited designs in an expeditious and economic manner. Responsibilities include ongoing design analysis, technical reviews of building design and construction, and Building Code compliance reviews at key milestones for all projects, as well as representation with Owner representatives, construction management staff, and regulatory agencies. As in-house LEED Professional I assist project teams in exceeding desired green building practice credits for bid and design/build projects.
Status: Unbuilt
Location: Sylmar, CA, US


text:
Model Type
32 Combined MPG (29 city / 37 hwy)
EPA estimated
A full list of available features and filters for the used 2017 Nissan Sentra inventory include but are not limited to: Edmunds Special Offers: Purchase Offers, Lease Offers, Gas Card (15), Used Offers (14). Model Type: Sedan (52), NISMO, SE-R Spec V, SE-R.
Trims: SV (27), S (20), SR (2), SL, 2.0 S, SR TURBO (3), 2.0 SR, 2.0, 1.8 S, FE+ S, 2.0 SL, NISMO, SE-R Spec V, GXE, FE+ 2.0 S, FE+ SV, 1.8, FE+ 2.0 SR, SE-R, SE, FE+ 2.0, XE. Features: Rear Bench Seats (52), Fold Flat Rear Seats (52), Aux Audio Inputs (52), Tire Pressure Warning (52), Trip Computer (52), Stability Control (52), Audio and cruise controls on steering wheel (52), Bluetooth (52), USB Inputs (52), Alarm (32), Back-up camera (32), Keyless Entry/Start (32), Heated seats (8), Sunroof/Moonroof (12), Navigation (4), Upgraded Headlights (5), Upgraded Stereo (3), Leather Seats (3), Blind Spot Monitoring (4), Auto Climate Control, Multi-Zone Climate Control, Power Driver Seat (3), Post-collision safety system (1), Pre-collision safety system (1), Adaptive Cruise Control (1), Automatic Emergency Braking (1), Upgraded Engine. Engine/Mechanics: 4 cylinders (50). Transmission: Automatic (41), Manual (2). Fuel Type: regular unleaded (47), premium unleaded (recommended) (3), premium unleaded (required). Drivetrain: front wheel drive (52).
New Car Resources
Used Car Resources
Car Articles & Advice
Follow Edmunds
The 2017 Nissan Sentra keeps up this popular sedan's reputation for offering plenty of value. With lots of interior room and trunk space, the Sentra could be considered a small car with midsize ambitions, and a wide range of trim levels and optional packages and accessories allow buyers to make it more of a premium car experience.
Having undergone a refresh last year, the Sentra has been only mildly tweaked for 2017. Changes include more comfortable seats, a larger center console and a quieter ride, courtesy of thicker window glass and better insulation. But the big news is the addition of the new SR Turbo model, which features a high-output engine, a six-speed manual transmission or a specially calibrated automatic CVT, and sport-tuned suspension.
Inside, there's a surprising amount of room for passengers and plenty of storage space for their belongings in numerous cubbies and the 15.1-cubic-foot trunk. Nissan prices the Sentra pretty aggressively, which will appeal to value-conscious shoppers, and available features still include such niceties as dual-zone automatic climate control, leather seating, a premium sound system and the NissanConnect system, which facilitates the use of smartphone-based apps.
All 2017 Sentra trim levels except the SR Turbo come with a 1.8-liter four-cylinder engine that produces 130 horsepower. The new SR Turbo model is powered by a turbocharged 1.6-liter engine that increases output to 188 hp. The base S model is equipped with a standard six-speed manual gearbox, and a continuously variable automatic transmission (CVT) is an option on the S and standard on all other trims, except the Turbo, which offers a choice of the two transmissions.
Power with the base engine is adequate but not particularly impressive when compared to many competitors. The standard suspension is tuned more for comfort and stability than handling, so although it provides a decent ride, cornering requires higher-than-average steering input and results in considerable body roll. Buyers seeking a bit more performance might want to test-drive the SR Turbo with its free-revving engine, which offers improved low- and mid-range zip. But even with its firmer suspension, the SR Turbo still doesn't excel in the handling department.
The best fuel economy in the Sentra lineup is achieved with the standard engine and the CVT, which returns an EPA rating of 32 mpg combined (29 city/37 highway). The lowest-rated model is the SR Turbo equipped with the manual transmission at 28 mpg combined (26 city/32 highway).
The base Sentra S comes very well equipped with features such as automatic headlights, air-conditioning and cruise control. Moving up to the SV trim level brings some extra comfort and technology items, while the SR adds on a number of sporty touches. The top-of-the-line SL piles on more luxury and convenience. Finally, the SR Turbo gives drivers more performance, as well as some unique styling touches and a host of additional features. Whatever your preference, let Edmunds help you find the 2017 Nissan Sentra that best meets your needs.
Unlock the ability to save and share your research, receive personalized price alerts on vehicles you're interested in, and access our Live Help Team.
Unlock the ability to save and share your research, receive personalized price alerts on vehicles you're interested in, and access our car buying experts.
Unlock the ability to save and share your research, receive personal price alerts on vehicles you're interested in, and access our Live Help Team.
Save the cars you want now, get alerts later We'll keep an eye on vehicles you've saved - then let you know when their price drops.
An email has been sent with a link to reset your password.
Know your password? Sign in now