# Functional testing a has\_many :through validation

**URL:** <https://www.ruby-forum.com/t/functional-testing-a-has-many-through-validation/168466>\
**Category:** Rails\
**Created:** [May 21, 2009, 3:25am UTC](https://www.ruby-forum.com/t/functional-testing-a-has-many-through-validation/168466 "2009-05-21T03:25:54Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Phoenix\_R](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/5e9695/32.png) [@Phoenix\_R](https://www.ruby-forum.com/u/Phoenix_R)\
**Post date:** [May 21, 2009, 3:25am UTC](https://www.ruby-forum.com/t/functional-testing-a-has-many-through-validation/168466/1 "2009-05-21T03:25:54Z")

</div>

The title of this post may be somewhat misleading; I am indeed UNIT  
testing this, and it works fine, however I’m also functional testing a  
POST to an action that is responsible for creating a new ActiveRecord  
object that’s associated with the “parent” via has\_many :through.

class Report \< ActiveRecord::Base

# …

has\_many :report\_notifiers  
has\_many :notifiers, :through =\> :report\_notifiers

# …

end

class ReportNotifier \< ActiveRecord::Base

# …

belongs\_to :report

# …

end

So, creating a new report with a new notifier would be simple:  
@r = Report.new  
@r.notifiers \<\< Notifier.create(:label =\> “something”, :email =\>  
“removed\_email\_address@domain.invalid”)

But what happens when a user submits invalid e-mail address? Well, of  
course, the validation fails. But how do I go about testing for the  
presence of that validation failure message in my functional test?

## Here’s my existing functional test:

def test\_edit\_with\_invalid\_notifiers  
m = Factory(:maintenance\_report) # I dig factory\_girl, great  
plugin

```
post :edit, {:m => m, :id => m.id, :notifiers => [1, 2, 3, '', 0,

```

‘asdfasf’, “\n\n;’;’’’’;UPDATE notifiers SET label=“hacked””],  
:new\_notifiers =\> “not a valid email!asdfasdfasf afd asdfasf 2  
wgw@a asdf…\n\n\n\removed\_email\_address@domain.invalid”}

```
# ...now what?

```

## end

As you can see, my test gives the controller action invalid data,  
which will trigger an error when the validation is attempted. But,  
given that the Notifier class, which contains the validation,  
belongs\_to the Report class, which is what I’m creating a new one of,  
how do I test to see if we get any errors?

i.e. in a template I’d just have:  
\<%= errors\_for :maintenance\_report %\>

…which would theoretically contain a bullet point saying something  
about “invalid e-mail address”. But how do I test that?

---

<div class="post-metadata">

**Author:** ![Phoenix\_R](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/5e9695/32.png) [@Phoenix\_R](https://www.ruby-forum.com/u/Phoenix_R)\
**Post date:** [May 21, 2009, 9:21am UTC](https://www.ruby-forum.com/t/functional-testing-a-has-many-through-validation/168466/2 "2009-05-21T09:21:47Z")

</div>

You should be able to do an assert\_select looking for whatever the \<%=  
errors\_for :maintenance\_report %\> generates for the error you are  
expecting. Or have I missed a subtlety of your question?

Colin

2009/5/21 Phoenix R. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

---

<div class="post-metadata">

**Author:** ![Phoenix\_R](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/5e9695/32.png) [@Phoenix\_R](https://www.ruby-forum.com/u/Phoenix_R)\
**Post date:** [May 21, 2009, 4:27pm UTC](https://www.ruby-forum.com/t/functional-testing-a-has-many-through-validation/168466/3 "2009-05-21T16:27:27Z")

</div>

Thanks for your reply Colin. In theory, there should be some way I  
can test for the presence or absence of errors on something like:  
@report.notifiers.errors.on (something?)

The thing is, since the post creates a new record for the associated  
model, I’m not quite sure how to “access” that.

---

<div class="post-metadata">

**Author:** ![Phoenix\_R](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/5e9695/32.png) [@Phoenix\_R](https://www.ruby-forum.com/u/Phoenix_R)\
**Post date:** [May 21, 2009, 6:14pm UTC](https://www.ruby-forum.com/t/functional-testing-a-has-many-through-validation/168466/4 "2009-05-21T18:14:16Z")

</div>

I think maybe  
assert assigns(:report).notifiers.errors.on(:fieldname)  
where fieldname is the field that you have added the error on.  
Or something like that anyway.  
If it doesn’t work you could break into the test code with the ruby  
debugger  
at that point, then you can inspect the variables and see what is where.

Colin

2009/5/21 Phoenix R. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

---

<div class="post-metadata">

**Author:** ![Phoenix\_R](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/5e9695/32.png) [@Phoenix\_R](https://www.ruby-forum.com/u/Phoenix_R)\
**Post date:** [May 21, 2009, 6:24pm UTC](https://www.ruby-forum.com/t/functional-testing-a-has-many-through-validation/168466/5 "2009-05-21T18:24:48Z")

</div>

Colin, thanks for your help. You got me thinking in a different  
direction.

I tried what you had there, but noticed that the test didn’t even get  
to that point. It failed IMMEDIATELY after the original post, so the  
assertion never fired. Which got me thinking: why not a rescue?

begin  
post :edit, {:m =\> m, :id =\> m.id, :notifiers =\> [1, 2, 3, ‘’, 0,  
‘asdfasf’, “\n\n;’;’’’’;UPDATE notifiers SET label=“hacked””],  
:new\_notifiers =\> “not a valid email!asdfasdfasf afd asdfasf 2  
wgw@a asdf…\n\n\n\t\removed\_email\_address@domain.invalid”}  
rescue ActiveRecord::RecordInvalid =\> e  
assert\_equal “Validation failed: Email is an invalid e-mail  
address.”, e.message  
end

This works perfectly. Thanks for your help!
