I want to run integration tests on my store filters e.g.
I filter by price and by different product attributes
are there pattern or best practices on how to assert on such a test, I'll illustrate an example:
Say I am calling a Repository.GetOnlyTShirtsWithColorRed() in my test db I have all the possible types of items.
I may get more then 1 item back but I want to assert that they all have a Red Color and they are all T-Shirts
I have re开发者_高级运维ad in many books that looping and iterating in tests in bad practice but how else may I assert that no mistake was done by my code, in a more complex query this may help to catch the bugs
From what I read - you want to test that your repository implementation works with a real DB - aka integration tests.
If the above is true, I think you're on the right path. My assert would probably look like
Assert.That(shirtsFromRepo.All(shirt => shirt.Color == Colors.Red), "all shirts were not red!)
As for the "best practice", can you post a link?
AFAIK the only recommendation is to avoid complicated logic in your code (e.g. ifs and other control structures) and testing one thing per test.
The best way to test this, is to mock the repository: By replacing the database (or web service, etc.) with a canned collection (array, list), you can control exactly how many red T shirts you have in your repository, thus you can tell your test to expect exactly a specific collection.
In C#, for example it might look like this:
public void GetRedTShirts_ReturnsAllItems()
{
Shirt[] allShirts = { new Shirt(Red), new Shirt(Green), new Shirt(Red) }; //collection for mock
// This depends on your mocking framework
var mockShirtRepository = new Mock<Shirt>(allShirts);
var expectedCount = 2;
// example of using dependency injection to replace the repository your controller would usually use in production, with a mock
var businessLogic = new Controller(mockShirtRepository.object);
var result = businessLogic.GetOnlyTShirtsWithColorRed();
Assert.AreEqual(2, result);
}
This way, you test your filtering logic, with a deterministic, known repository, not breakable by your repository.
If what you want is to actually test your implementation of a repository, then I suggest that you run your tests against a known, canned, data-store (i.e. you will have a set of T-Shirts in the shirts table, and you will know exactly which shirts are red), so that you can assert that the repository returns exactly what you expect it to.
However, such tests are expensive, and aren't really unit-tests per-se. In order to improve performance, and bring the run-time down to acceptable values, you may wish to run against an in-memory database, such as SQLite. It's free, btw.
That way, you will not have to loop or iterate over tests. You will simply call your repository and verify the results:
public void GetShirts_WithFilter_ShouldReturnFilteredResults()
{
var rep = new MyRepository(mySQLiteConnectionString);
var redShirts = rep.GetShirts(shirt => shirt.Color == Color.Red); //For example
Assert.AreEqual(3, redShirts); // I know there should be 3 red shirts in the table
}
Alternatively you can prepare a collection (e.g. IEnumerable of Shirt) with the exact list of shirts you expect to get, and assert that the lists have the same items.
Hope this helps.
精彩评论