Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>Joe. I feel a lot of the same uncertainty, sometimes. But I also think that most of what you're missing is those up-front stories. First, you should decompose your story just a tad to create the actual developer requirements. Here's what I mean:</p> <blockquote> <p>"A user must be able to add a widget, doing so they are taken to view the details of the newly added widget."</p> </blockquote> <p>Ok, so to me, that breaks out questions as follows, which can help you think of tests:</p> <p>"A user" -- where did the user come from? How are they logged in? (if you're using the default AccountController and tests, then this is already there, if not, you'll want tests for getting the login form, logging in, validating both successful and failed logins, etc)</p> <p>"add a widget" -- to what (I don't mean implementation, I just am pointing out that this implies that you're either going to hit a repository or a service, unless 'add' just means add it to the running instance and you don't need persistence)? does the widget have to be valid at this point, or can invalid widdgets be saved and made valid later? This implies to me tests that a repository or service has a method hit (save(), insert(), add(), whatever (not the internals of the method, until you get to testing your service/repo, just that the controller does its job by calling it), check what happens on a valid/invalid widget (you need to expand your story a bit or add a story to cover what should happen on valid/invalid widgets)</p> <p>"doing so they are taken to view the newly added widget's details" -- reworded slightly, but basically what you said. Always? or only on success? Is this view editable or read-only (i.e. Edit action or Details action)? Is there a message to the user that tells them that they've been successful, or should they infer from the fact that they're viewing their widget that they were successful? This should drive tests that do things like check properties on the returned actionresult and check the values stored in TempData (status message) as well as checking what happens in both paths (success or failure). </p> <p>that's just a quick shot, but basically that's the thought process. you can also do the same w/ other stories, and for that matter generate new stories to cover more application behavior.</p> <p>A couple thoughts on your design going forward. </p> <p>Your next test should look at what I wrote above first, which is the fact that the controller's create POST action should 1) receive needed data (your params), 2) call that service/repository to "add" the widget, 3) possibly do something if that add fails (this is in your design; I've gotten to where my controllers assume all will go well and I handle failures through attributes, but thats' a personal design decision), 4) redirect to details.</p> <p>So, your next test would be using a mock (I prefer the moq library on google code, but whatever you have will work). You'll need some interface to describe the service your controller will call, and you pass in a mocked implementation of that to your controller under test in order to ensure that it's calling the correct method. In Moq, that'd look something like this:</p> <pre><code>[Test] public void Create_CallsRepository() { // Arrange var currentUser = new User { DisplayName = "Fred", Email = "fred@widgets.com", Password = "pass", Status = UserStatus.Active }; var model = new WidgetModel(); var mockService = new Mock&lt;IService&lt;WidgetModel&gt;(); mockService.Setup(s=&gt;s.Add(model)); //.Returns(whatever) if it returns something var controller = new WidgetController(mockService.Object); // Act var actionResult = controller.Create(currentUser, model); // Assert mockService.Verify(s=&gt;s.Add(model)); } </code></pre> <p>That makes some design assumptions, of course, but the tension of how to write your tests vs how your objects should be called / handle things is part of what makes TDD so valuable. </p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload