I understand from Techtalk that coupling step definitions to features is an anti-pattern.
However I am wondering how to organise my step definitions so that I can easily see in the code what steps go together.
For example should I create a code file for each Feature and a separate file for steps that are shared? or should I have a code file for a set of features?
I tend to organize step definitions in a couple of ways, depending on how big the step definition files get.
Separate data and UI steps
I have lots of Given some thing exists in the database steps, so I usually throw these into a file call DataSteps.cs. I also have lots of Then something exists in the database steps and those go into DataAssertionSteps.cs.
All of my When I fill in some form field steps go in FormSteps.cs. Anytime I need Then something in the form is enabled|disabled or asserting that form fields have a certain value, I throw those into FormPresentationSteps.cs.
Separate Steps by Model
Sometimes my step definition files get very large, and I start moving step definitions into files related to a certain model. Say I have a Person model. I might create a PersonSteps.cs file that is split into three regions:
[Binding]
public class PersonSteps
{
#region Given
// Given a person exists with the following attributes:
#endregion
#region When
// When something something about a Person
#endregion
#region Then
// Then a person should exist with the following attributes:
#endregion
}
Basically I start out with these files:
DataSteps.cs - The Givens for setting up test data
DataAssertionSteps.cs - The Thens for asserting that data exists correctly in the database
PresentationAssertionSteps.cs - Just general stuff making sure the UI looks as itshould
FormSteps.cs - Steps for manipulating forms
FormPresentationAssertionSteps.cs - Making sure form fields have the proper values, are enabled/disabled correctly. Validation messages show up, etc.
GeneralSteps.cs - A poorily named catch-all for stuff that doesn't fit in the above files. Maybe I should rename it "AndIShallCallItSomethingManagerSteps.cs"?
Related
This is probably the single biggest time-waster I have: I must have wasted cumulative days trying to get round it.
I'm using Visual Studio 2015 and ASP.NET MVC 5, but don't think this is important - I've had this problem in other versions. I accept that it's based on my ignorance.
I've got a reasonably complicated SQL Server database, and am using database-first model generation. To keep things manageable, I've got about 20 different models, each containing tables on a particular theme.
So let's say I want to generate a model to contain tables to do with the maps in my database. First thing to do is to add a new entity model database:
I want to call my model webMap:
I choose to generate the model from my database:
I've got a perfectly good connection string to the database in my web.config file, so I use that and choose not to save this:
I then choose the tables for which I want to generate classes, and these options:
What happens then is that it doesn't recognise the new database context:
The reason is (I think) in this file:
This has created a class named after a connection string:
If I change the partial class and constructor name like this:
then it solves the problem - until I next need to update the database.
Please forgive my ignorance about what's going on. Although I like what entity frameworks do, I find the opacity of what's going on hard to work with. Could any kind person tell me what I'm doing wrong, without delving into T4 transformations? I've tried cleaning my solution and running custom tools, by the way. Thank you!
Open the edmx file in the designer and click somewhere inside to select the conceptual model in the Properties window. Now look at Entity Container Name property. The value should be Entities - I think derived from your connection string name and no way to be specified during the Add wizard steps.
Simply change it to the desired name of the context (like webMap), save/build and you are done.
But make sure the Namespace and Entity Container Name property values are different.
Many thanks to Ivan and garret for their answers. I've collated the information and put here a procedure which worked for me. I don't claim to understand fully what's going on (but surely the point of a framework like this is that I shouldn't need to?).
Here's how I managed to create my model. There are 6 steps. I don't know which of them can be omitted, but following them all solved my problem.
Step 1 - Delete any existing models referencing tblMap
I found that I had inadvertently created another model. Doing a global search for (in my case) webMap can help find if you are in the same position.
Step 2 - clear the web.config file connection strings
I don't understand why, but it appears that the connection strings in your web.config file show up as conflicting names in code. So I did a search for webMap in my web.config file and deleted all connection strings containing it. I think this is the step that I had previously omitted.
Step 3 - Clean and rebuild the solution
I cleaned the solution (no idea if this was necessary), then rebuilt it to ensure that the only errors I had left were in my code referencing the webMap database context which no longer existed.
Step 4 - Follow the steps to add an ADO entity model
But ... call the item name in the first screen something like webMapModel, the connection string something like webMapEntities (and choose to save this in the web.config file) and the namespace something like webMapNamespace. Note that none of these is the webMap name I want to end up with.
Step 5 - Change the entity container name
Double-click on the model .edmx file which has been created to open it (this might not be necessary - it may be open already). Click on the white background of the model to deselect any entities. Press F4 to bring up properties.
Change the entity container name to webMap as shown above.
Step 6 - Rebuild your solution
At this point all my errors disappeared!
Name of Your context, should be different than namespace.
Try to use this configuration:
And in next screen:
And yes, it will add next connection string to web.config, but it's ok.
I'm using ViewModels in MVC. I'm find them incredibly klutzy and wonder if I'm doing something wrong. (Let's leave Automapper out of this for the sake of discussion.) I use viewmodels to send data to the client as well as receive form submissions. Some properties are sent to the browser for display only, others are sent & retrieved (eg. fields).
I typically have to implement the following to make a viewmodel work:
1) Create a view model class
2) Create a general function to initialize the view model & copy the properties from my entities & other sources
3) Write more code to write some values from the viewmodel back to the entities (or other destination) on submission
4) If there are server side validation errors, I need to write more code (particularly messy) to repopulate the read-only parts of the viewmodel (which were included in the submission), while taking care to not overwrite the user submitted data.
For a simple property (eg. "myViewModel.FirstName") this requires code to be written in no less than 4 places. That's not including the stuff in the Domain and Views. This pattern seems fragile to me - it's easy to break code eg. forget to implement a change in all locations. Definitely not DRY.
Am I missing the point or do all patterns using ViewModel have this kind of klutziness?
I'm not sure what you find klutzy? MVC is about separation of concerns. Keeping your business logic, data layer and GUI code separate. This in itself makes your code easier to manage, easier to test and far less confusing to debug.
And lets look at your four points.
Point 1. Firstly is creating a POCO for your view model really that much of an issue? I'd say not, since you can accomplish this in around 3 lines of code, given your example. And should your model need to change, would it not be more beneficial for it to be in its own view model class rather than in code directly in every action method in every controller where you may have used it?
Points 2 + 3. Here you speak about going from data layer to logic layer to view and back again. This is the whole point of MVC. Just because you have to possibly code three classes (model, service, repository) to handle this transaction does not make this cumbersome, it makes it clean. Just imagine if you dumped all this together on the controller action method. How would you handle re-use? How would you prevent repetition of code in other actions or controllers? Things would start to get very difficult.
Point 4. I don't really see this as a valid argument since you can just pass back the model submitted by the user without any need to update it or edit it. By using data annotations and ModelState for validation it is very simple to create a clean and testable unit of code. So I imagine that its not the fact your using a ViewModel but perhaps more to do with your implementation.
I'm new to the whole ASP world and I'm getting my feet wet by building a C# MVC3/EF4 project. I'm finding it hard to keep from duplicating a bunch of code in my models and view models. Consider an object Foo. I need to do the following things with Foo:
Store records of type Foo in my database.
Allow users to lookup records of an individual Foo (pass instances of Foo to a view).
Allow users to create new instances of Foo (pass instances of Foo to a form).
Let's say I also have a type Bar. A Bar contains a list of Foos. There are two requirements here:
Users can view a list of Bars.
When the user clicks on a specific Bar, it shows all of its Foos.
So, a sketch of my basic objects look like this:
class Foo
{
string FooName;
int Id;
}
class Bar
{
List<Foo> FooList;
int Id;
string Baz;
}
But when I start thinking about the different views, it begins to get messy:
The views shouldn't have any write access to any of the data members.
There's one view that takes a list of Bars but doesn't care about Bar.FooList. Let's say I also want to be good about resource management and close the DbContext as soon as possible (i.e. after the object is in memory but before I render the view). If I just pass it a list of Bars and the designer tries to access the FooList by mistake, we'll get a runtime error. Yuck!
Ok fine, I just create a distinct ViewModel for each view that has read only datamembers, no problem.
But both the database model and the form models will need to have DataAnnotations attached which say which fields are required, max length of the strings, etc. If I create separate form models and database models then I end up having to duplicate all these annotations. Yuck!
So, that's my architectural dilemma: I want to have succinct view models which restrict the views only to reading the data they are supposed to access. I want to avoid repeating data annotations all over the place. And I want to be able to aggressively free my DB resources as soon as possible. What's the best way to achieve my goals?
My advice is do NOT use data annotations in your EF entity classes. Instead, try out the fluent API. It keeps persistence concerns out of the model classes themselves. You can even define the modelbuilder stuff in an entirely different library.
As for having duplicate properties, properties are cheap:
public string MyProp { get; set; }
Not a lot of code, and you may begin to see, the viewmodels and entities need not always be exact duplicates of each other. For example, what if you want to apply [HiddenInput] to a viewmodel, to get it to render as <input type="hidden" />? Would you apply that to the entity? Why? It belongs in the viewmodel (the namespace is even System.Web.Mvc, not System.ComponentModel.DataAnnotations).
As far as duplicating error messages during validation (if you validate the MVC and EF layers separately), you can use resx resources.
As far as freeing db resources, let EF manage that. I find it's best to keep a single DbContext instance per HttpContext. You can open it up using a factory, an OnActionExecuting action filter, Application_BeginRequest, with an IoC container, or whatever. Then dispose context during OnResultExecued, Application_EndRequest, etc. Keeps things simple.
I´ve not had much contact with Entity Framework yet and therefore I´d like to hear some guys with experience.
I´ve got an MVC project and my DataAccess lies in a different project where I want to place my EDMX file.
So how would I like to name this file? Per default it is "Model1.edmx" but in the context of MVC I don´t feel comfortable with this name. Is it really a Model?
I tend to call it "DbModel" or something to indicate that it is database related stuff.
And how do you guys call the entity class? I think I like the EF typical name "DbContext".
So within my controllers I´d have something like
public class WorldController : Controller
{
DbContext db = new DbContext();
public ActionResult Own()
{
var allContinents = db.Continents;
[...]
}
}
Sorry for being fussy but I really do care about naming.
It is good to care about naming!
How to do it depends on the composition your application. Let's say you have a web application for registering UFO sightings, to name something common. If there is a separate part of your db (maybe a separate schema) containing users, roles and permissions, you could create a context named AuthorizationContext, and for the business part a context named UfoDbContext.
I mean, if there are clear aggregates with no or little overlap you could create separate contexts for them with clear names. If one context fits the bill, I would still give it some meaningful name (not DbContext) that relates to your application domain.
There are people (I'm not one of them) that like to work with one context per application "column" (db to UI) or "user story". Meaningful names are even more important then.
My suggestion would be to use something that indicates the contents in the naming. You could take part of your project name, for instance, and bring it down into the name of the EDMX. Include something that makes it less generic.
I also tend to include an "Ef" in my naming, which I started when working on a project that already had an existing ORM.
To take Microsoft's prototypical example: if your project fell under the umbrella name of Norwind, here's how I would name some of the files in my model project:
EDMX File:
NorwindEfModel.edmx
Generator/TT File:
NorwindEfDbContext.tt
Entities class:
NorwindEntities
I can't say this is exactly how Microsoft would have it if you downloaded a sample project from them (though I believe it would be similar), but I think it's a reasonable naming structure and it fits my needs. The bottom line is this largely comes down to opinion and your need for specific distinction.
In most documentation you read about ASP.NET MVC, the entire 'Separation of Concerns' is very heavily pushed. Dependency Injection/Inversion of Control, Unit Testing, keeping 'logic' out of the Views, etc.
But how far is this intended to be pushed? Is it bad practice if a specific task requires extra logic beyond the 'three layer' approach of View/Model/Persistence?
For example, I have a solution set up with four individual projects.
Project.Web (ASP.NET MVC) [ References Data.dll, Models.dll ]
Project.Data (Fluent nHibernate Mapping) [ References Models.dll ]
Project.Models (POCO, Helpers, Factories, etc)
Project.Tests (Unit Testing)
Up until now, this has served me pretty well. But I require some very abstract logic for some of my MVC Views, such that I need to take part of the Models and arrange a View Model that is persisted in the database.
This cannot happen in my Data section, as that would dispose the re-usability of it, and there is business logic included in the process. It cannot entirely happen in my Models section, because that would require it to have knowledge of the Data section, which it does not. And I do not want to put it in the Web section because I don't want data access code there.
Question
Is it in massive violation for me to add, say, a Project.Presentation project that references Data.dll and Models.dll to construct what I need to? Moreover project concerns aside, is this a bad approach in general or is this something a lot of you find yourselves having to do at times? Part of me feels that if I am having to resort to this, then I've just built my software wrong - but at the same time I am very confident I have done a fairly good job, it is just too abstract to make a raw HTML interpretation of without middle-man arrangement.
It's been my experience that single responsibility is a great way to write code you expect to change early and often. Like Jan, I too have a solid line between who does what, when. The more you enforce this, the easier it is to replace an slice of your system. I recently removed linq2sql with EF4.1 and because of SRP, once I got the tests passing around my new EF4 layer, everything else just worked.
That said, I typically let unit testing dictate where these things live -- it's my driver for SRP as well as asking the basic question "must =class/service= know about =something else= to do it's job?" If the answer is no, it goes somewhere else -- if yes, it's a dependency. Now, if it becomes painful, that's its way of telling me "this is stupid" (see this question for the stupid) and I've attempted to force something instead of allowing it to fit the way it must.
Onto your core queston : you've clearly identified a gap in your code -- it MUST know about two things (data and model) and I agree, it should be its own thing and pulled out. I would call this a "DomainService" or maybe just DTO, but presentation feels like it would be doing more than just prepping data. (I'd argue the view handles the presentation ... maybe you simlpy mean presenter?). I would also argue against your perception that you did "something wrong" - no, you're learning to write code differently and allowing it to evolving, EXACTLY as it should. :-)
I use the following structure, which more or less solves all problems we've had regarding MVC structures.
Models: contains all ViewModels. Just clean, only getters and setters.
Business logic implementation: Set of projects that contains database logic, DAL entities etc. But only has one interface (in our case this is a WCF API).
ServiceLayer: the bridge between Business Logic and ViewModels. Doesn't know anything about web.
Mapping layer: translation between business entities and ViewModels.
Web project: holds very thin Controllers and Views, and everything web related.
A web page flow will follow this flow:
URL maps to a certain Action
Actions are really clean, they only reference a method in the ServiceLayer
The ServiceLayer executes one or more actions in the Business Logic Implementation (get data, store data, etc.)
The ServiceLayer passes the business entities to the Mapping Layer.
The Mapping Layer translates business entities into ViewModels
In code this would look like:
// action
public ActionResult ListOfObjects () {
var model = new ServiceLayer.ObjectsClient().GetListOfObjects();
return View(model);
}
// Service Layer
public ListOfObjectsModel GetListOfObjects () {
var businessEntities = BusinessDao.GetThingysFromDb();
var model = Mapper.TranslateToViewModel(businessEntities);
return model;
}
// Mapping Layer
public ListOfObjectsModel TranslateToViewModel(List<BusinessEntity> entities) {
// do mapping
}
When handling POSTs you will follow the same flow, but the mapping layer should translate your ViewModel into Data Entities that are given to the Business Logic.
"take part of the Models and arrange a View Model that is persisted in the database"
Then its not a viewmodel.
Does that simplify things?
What is a 'ViewModel':
More than often 'ViewModel' is confused with persistence. If you look at the word more closely it is a combination of 'View' + 'Model' - which essentially means it is a single unit of data that is required to fulfill all the needs of your view. A ViewModel can infer multiple entities or sources to build what is required by the View.
Now Coming to your question:
Is it in massive violation for me to add, say, a Project.Presentation project that references Data.dll and Models.dll to construct what I need to?
Re: If I had to do it, I would have created a seperate namespace (folder) in my MVC project named 'ViewModels' and placed all my Viewmodels in there. In my opinion if you want your ViewModels to be in a separate namespace, it would not actually violate MVC. You are just incresing the separation or making it more unit test friendly.
Just my 2 cents!!!