I am trying to test my real data by actually hitting the database. I am actually testing my Repository classes. Here is an example of what I am doing;
/// <summary>
/// Summary description for Country
/// </summary>
[TestClass]
public class Country {
public Country() {
_countryRepo = new CountryRepository();
}
private ICountryRepository _countryRepo;
[TestMethod]
public void db_should_return_at_least_one_country_as_approved_all() {
//Act
var model = _countryRepo.GetAll();
//Assert
Assert.IsTrue(model.Count() >= 1);
}
[TestMethod]
public void db_should_return_at_least_one_country_as_approved_true() {
//Act
var model = _countryRepo.GetAll(ApprovalStatus.Approved);
//Assert
Assert.IsTrue(model.Count() >= 1);
}
[TestMethod]
public void db_should_return_Turkey_as_country_name_by_id() {
//Act
var model = _countryRepo.GetSingle(1000);
//Assert
Assert.AreEqual<string>("Turkey", model.CountryName);
}
[TestMethod]
public void db_should_return_Turkey_as_country_name_by_countryISO3166Code() {
//Act
var model = _countryRepo.GetSingle("TR");
//Assert
Assert.AreEqual<string>("Turkey", model.CountryName);
}
[TestMethod]
public void db_should_return_Turkey_as_country_name_by_GUID() {
//Act
var model = _countryRepo.GetSingle(Guid.Parse("9AF174A6-D0F7-4393-AAAD-B168BADEDB30"));
//Assert
Assert.AreEqual<string>("Turkey", model.CountryName);
}
}
This works pretty well for my needs but wondering if I am doing it right by the book. Is there any other patterns that I really should be following here. I do not want to fake my data, my real intense here is to test my DAL and real production data.
Your tests will fail if someone else (or even you) go to your database and create a new approved country or change your country name. You are going to think: "WTH is wrong with my repository, why is it not working as expected?" But yeah, the problem isn't with the repository.
When I write tests that hit the database I like to create the DB and load default values at startup and destroy then all right after that. I'm not sure if this is the best alternative, but it works pretty well. The problem with this approach is that it's slower and there is more to code.
For the requirement at hand, i.e. data that is really static, and should not be tampered with, I'd say this is a valid approach.
I would recommend to write data-driven tests however, instead of repeating the same test case for each country.
You should use static database just for testing and your methods testing GetAll should assert against real expected count. How do you know that it really returned what you expected if you just assert that it returned at least one record? You should even go through result set and test that all records satisfy the condition (but it is usually used for more complicated conditions).
Related
I need to add a method to a model that given some parameters assigns a value to one of the model's fields.
public class ModelName: SomeModel<ModelName>, IModelName
{
[Field]
public string SomeField{ get; set; }
[Field]
public string FieldSetByMethod{ get; set; }
public new async Task MethodToSetField(string parameter)
{
var someClassInstance = new SomeExternalClass(parameter);
FieldSetByMethod = someClassInstance(parameter).method();
}
}
Now when I'm writing unit tests and I want to have a way of checking that this MethodToSetField was called. However, I can't really actually call the MethodToSetField method as creating SomeExternalClass is not desirable (e.g. because it creates unique ID).
I don't really have experience with neither C# nor Moq. How can I mock this function so it behaves more or less like this:
ModelNameInstance.Setup(c => c.MethodToSetField("Parameter")).Assigns(FieldSetByMethod,"DummyValue");
Or maybe I can somehow restructure the code / write tests in a way to imitate this behavior?
You could inject ISomeExternalClass into this class and then mock it, and test against the mock, or if you can't do that - inject ISomeExternalClassFactory into this class and then mock it. ISomeExternalClassFactory mock would return a mock of ISomeExternalClass that you could setup and test against.
I am writing test for a class thats manage trees of Tag objects:
public class Tag
{
public virtual int Id { get; set; }
public virtual string Description{ get; set; }
private IList<Tag> children = new List<Tag>();
public virtual IEnumerable<Tag> Children
{
get {return children .ToArray();}
}
public void AddChildTag(Tag child)
{
children.Add(child);
}
public void RemoveChildTag(Tag child)
{
children.Remove(child);
}
}
As you can see the only mode to set the parent property is via the AddChildTag method and this is exactly what i want, my problem is in unit test: since every test should be atomic, how can i test the RemoveChildTag method?
Only way i see is a call to the add method and later to the remove, but in this way if Add as some errors, even the test of remove will fail, so atomicity is lost.
How can that be done?
EDIT
I removed parent property from Tag object, since i no more use it
Some test according to solution using NUnit and FluentAssertion
[Test]
public void AddChildTagAddsChildren()
{
//Arrange
Tag parent = new Tag();
Tag child = new Tag();
//Act
parent.AddChildTag(child);
//Assert
parent.Children.Should().Contain(child);
}
[Test]
public void RemoveChildTagRemovesAddedChildren()
{
//Arrange
Tag parent = new Tag();
Tag child = new Tag();
parent.AddChildTag(child);
//Act
parent.RemoveChildTag(child);
//Assert
parent.Children.Should().NotContain(child);
}
[Test]
public void RemoveChildTagThrowsNothingWhenNoChild()
{
//Arrange
Tag parent= new Tag();
Tag child= new Tag();
//Act
Action RemoveChild = () => parent.RemoveChildTag(child);
//Assert
RemoveChild.ShouldNotThrow();
}
Your unit tests should reflect actual use cases of your class. How will your consumers use RemoveChildTag method? Which makes more sense? Which is how you'd use collection of objects?
var parent = new Tag();
// later
parent.RemoveChildTag(child);
… or
var parent = new Tag();
parent.AddChildTag(child);
// later
parent.RemoveChildTag(child);
Your consumers will remove objects they previously added. This is your use case, "Remove removes elements previously added" (note that it also produces excellent test method name).
Add and Remove methods are often complementary - you can't test one without the other.
There are some ways to test Remove method:
Mocking - mock your data structure, and call remove , so you can test calling the right methods
Inheritance - make children protected. Your test class will inherit from Tag class. Now you can init children member so we can test the remove
Use Add Method
I think option 3 is the best, it's ok using other methods in your unit testing, if Add have some error , more then 1 test will fail - you should be able to understand what you need to fix.
Also, each unit test should test some basic behavior, even if you need to do some preparation before.
If those preparation failed, fail the test with the relevant comments
Option 1 - is best when you code is reaching to 3rd party - other server, file system & more. Since you don't want to make those calls in unit test - mock the response.
Option 2 - best I can say , is when you want to test protected / private method, without needing to make all the calls "on the way" that your code does (public method that make many calls that eventually call the method you want to test), since you want to test only a specific logic. It also easy to use this option when your class have some state that you want to test, without needing to write a lot of code to bring your class to this state.
You could use an PrivateObject Class to Arrange your object under test
Allows test code to call methods and properties on the code under test
that would be inaccessible because they are not public.
EDIT
then you could get full access to wrapped object by PrivateObject.RealType and PrivateObject.Target Properties
EDIT
Anyway, every system which break the segregation and encapsulation of a class make useless the black box approach of Unit Testing in TDD and should be avoided as a poison :)
A common approach to unit testing is the Arrange-Act-Assert paradigm.
I would personally have two tests for the remove method, one which is removing a child which was never added, what should happen? Should an exception be thrown?
This would look like:
[Test]
public void RemoveChildTagThrowsExceptionWhenNoChildren()
{
// Arrange
var tag = new Tag();
var tagToRemove = new Tag();
// Act & Assert
Expect(() => tag.RemoveChildTag(tagToRemove), Throws.ArgumentException);
}
Then I would have another test for what should happen when an added child is removed:
[Test]
public void RemoveChildTagRemovesPreviouslyAddedChild()
{
// Arrange
var tag = new Tag();
var childTag = new Tag();
tag.AddChildTag(childTag);
// Act
tag.RemoveChildTag(childTag);
// Assert
Expect(tag.Children.Contains(childTag), Is.False);
}
It may be of interest to note that quite a lot of .NET Remove implementations return a bool result which indicates whether any removal was actually performed. See here.
I am trying to do some unit tests and I need dummy data. Some of this data I need to have specific values, other will be just random.
I have for instance a "CreateProduct" method in my Service Layer and I am wondering if it is a good idea to use such methods instead of making a product by hand in my unit tests.
On the surface this seems like a good idea but I am worried maybe I will need to mocking or something to successfully get through that method.
The CreateProduct will try to save the product to the database but I have already a flag that will stop the save happening(used for unit of work scenario encase of rollbacks).
I am using EF 6-rc1 and mocking up the DataContext with moq and I was going to use AutoFixture but it does not work out of box for this secnario and I am starting to feel I am taking too much new tools on at once so maybe I should just do it manually for now.
It's hard to tell exactly what you are doing without a code example, but I sometimes use this implementation of an IDataSet that uses a List in memory. Typical usage would be something like:
using System.Data.Entity;
using System.Linq;
using Moq;
using NUnit.Framework;
namespace EFMock
{
internal interface IDataContext
{
IDbSet<DataItem> DataItems { get; set; }
}
class DataContext : DbContext, IDataContext
{
public IDbSet<DataItem> DataItems{ get; set; }
}
class DataItem
{
public int SomeNumber { get; set; }
public string SomeString { get; set; }
}
/* ----------- */
class DataUsage
{
public int DoSomething(IDataContext dataContext)
{
return dataContext.DataItems.Sum(x => x.SomeNumber);
}
}
/* ----------- */
[TestFixture]
class TestClass
{
[Test]
public void SomeTest()
{
var fakeDataItems = new [] {
new DataItem { SomeNumber = 1, SomeString = "One" },
new DataItem { SomeNumber = 2, SomeString = "Two" }};
var mockDataContext = new Mock<IDataContext>();
mockDataContext.SetupGet(x => x.DataItems).Returns(new FakeDbSet<DataItem>(fakeDataItems));
var dataUsage = new DataUsage();
var result = dataUsage.DoSomething(mockDataContext.Object);
Assert.AreEqual(2, result);
}
}
}
I also have a NuGet package named "FakeO" that you can use to create some fake objects, where some data is a specific value and some is random:
var fakeDataItems = FakeO.Create.Fake<DataItem>(10, // create an IEnumerable of 10 items
x => x.SomeNumber = FakeO.Number.Next(), // set to a random number
x => x.SomeString = "Always This String"); // set to a specific string
One thing to keep in mind with this kind of testing is that using an IQueryable against a List will use Linq2Objects and not Linq2Entities, so results of some Linq queries will be different.
If you want to Unit Test something, you'll just want to test the unit. If you use a method in the servicelayer to generate some fake data, the unit test is not only testing the unit under test, but also the method in the service layer.
So the answer to your question: no, it is not a good idea to use the service layer to dummy data
I'm having an issue where AutoFixture seems to be overwriting a property on a frozen mock. The property on the mocked class is read-only, and from what I've read, AutoFixture shouldn't be trying to do anything with it.
I've included code to reproduce the issue in LINQPad below. Victim is a trivial test class with two read-only properties. At issue is that once I have set the expectation for the Things property and registered the mock's Object as the instance for AutoFixture to return for the Victim type, the collection Things contains different strings.
To reproduce the problem, run the code below in LINQPad as a C# Program and reference AutoFixture and Moq from NuGet. Be sure to include the namespaces Moq and Ploeh.AutoFixture.
My expectation is that I should get back the object I registered with Register and that the collection Things in the returned Victim should return the collection I referenced in my call to SetupGet.
public class Victim
{
private string _vic;
private IEnumerable<string> _things;
public virtual string VictimName { get { return _vic; } }
public virtual IEnumerable<string> Things { get { return _things; } }
}
void Main()
{
var fixture = new Fixture();
var victimName = fixture.CreateAnonymous("VIC_");
var things = fixture.CreateMany<string>();
victimName.Dump("Generated vic name");
things.Dump("Generated things");
var victimMock = fixture.Freeze<Mock<Victim>>();
victimMock.SetupGet(x => x.VictimName).Returns(victimName).Verifiable();
victimMock.SetupGet(x => x.Things).Returns(things).Verifiable();
fixture.Register(() => victimMock.Object);
var victim = fixture.CreateAnonymous<Victim>();
(victim.Equals(victimMock.Object)).Dump("Victims are the same?");
victim.VictimName.Dump("Returned name");
victim.Things.Dump("Returned things");
(things.Equals(victim.Things)).Dump("Returned things are the same?");
victimMock.Verify();
}
My guess is that the Iterator for Things is actually the same, but that the strings it generates are different. This is actually by design, although we've later come to realize that this wasn't a particularly good design decision.
In AutoFixture 3, this behavior has been changed.
If I've guessed correctly, this issue will go away in AutoFixture 3. In AutoFixture 2 you should be able to resolve it by creating the fixture like this:
var fixture = new Fixture().Customize(new StableMultipeCustomization());
This post is meant to be more a discussion-starter, as I am somewhat new to unit testing and TDD.
I am currently writing some unit tests for a .NET process that interacts with several databases, and am using mock database contexts in an attempt to cover different edge cases within my tests, verify exception handling in the program itself, among other things. That being said, some of my unit tests use valid data, while others do not.
I am looking for feedback in terms of suggested best practices when adding valid/fake data to your mock database contexts. I've seen people do this a number of ways (e.g. - implement repository pattern, adding mock data to .csv files and making them part of the project, etc...).
I'm currently thinking about using a repository pattern for adding Survey objects to the Surveys table in my target DB.
First off, I've got the interface:
public interface ISurveyRepository
{
IQueryable<Survey> SurveySeries { get; }
}
This is implemented both for the mocking fake/valid data repositories as needed by unit tests
class FakeSurveyRepository : ISurveyRepository
{
private static IQueryable<Survey> fakeSurveySeries = new List<Survey> {
new Survey { id = 1, SurveyName="NotValid1", SurveyData="<data>fake</data>"},
new Survey { id = 2, SurveyName="NotValid2", SurveyData="<data>super fake</data>"},
.........,
new Survey {id = 10, SurveyName="NotValid10", SurveyData="<data>the fakest</data>" }
}.AsQueryable();
public IQueryable<Survey> SurveySeries
{
get { return fakeSurveySeries; }
}
}
// RealSurveyRepository : ISurveyRepository is similar to this, but with "good" data
I then have a class to consume this data for either fake/valid data by being passed a reference to the series in the constructor:
public class SurveySeriesProcessor
{
private ISurveyRepository surveyRepository;
public SurveySeriesProcessor( ISurveyRepository surveyRepository )
{
this.surveyRepository = surveyRepository;
}
public IQueryable<Survey> GetSurveys()
{
return surveyRepository.SurveySeries
}
}
And can then approach using these objects in my tests such as:
[TestClass]
public class SurveyTests
{
[TestMethod]
WhenInvalidSurveysFound_SurveyCopierThrowsInvalidSurveyDataErrorForEach()
{
// create mocking DB context and add fake data
var contextFactory = new ContextFactory( ContextType.Mocking );
var surveySeriesProcessor = new SurveySeriesProcessor( new FakeSurveyRepository() );
foreach(Survey surveyRecord in surveySeriesProcessor.GetSurveys() )
{
contextFactory.TargetDBContext.Surveys.AddObject( surveyRecord );
}
// instantiate object being tested and run it against fake test data
var testSurveyCopier = new SurveyCopier( contextFactory );
testSurveyCopier.Start();
// test behavior
List<ErrorMessage> errors = testSurveyCopier.ErrorMessages;
errors.Count.ShouldEqual( surveySeriesProcessor.GetSurveys().Count );
foreach(ErrorMessage errMsg in errors)
{
errMsg.ErrorCode.ShouldEqual(ErrorMessage.ErrorMessageCode.InvalidSurveyData);
}
}
}
NOTE: I realize that in the example code provided I don't necessarily need to make the classes implementing ISurveyRepository return the series as an IQueryable<Survey> (they could very well be List<Survey>). However, I am going to extend the functionality of the interface and these classes in the future to filter out the fake/valid series based on certain criteria added to LINQ queries, which is why I made the repositories implement IQueryable<>. This is mock-up code designed to convey the basic principles of what I'm thinking.
With all of this in mind, what I'm asking is:
Do you have any suggestions in terms of alternative approaches I could take in such scenarios?
What methods have you employed in the past, what did you like/not like about them? Which have you found were the easiest to maintain?
Given what I've posted, do you notice flaws in my general approach to unit testing? Sometimes I feel as though I write unit tests that attempt to cover too much ground instead of being concise, elegant, and to-the-point.
This is meant to be somewhat of an open discussion. Please keep in mind, this is the first set of unit tests I've ever written (I've read a decent amount of literature on the subject, however).
I think you're on a good track.
Personally, in the same situation, if I were dealing with a repository style pattern,
public interface IRepository<T>
{
IEnumerable<T> GetAll();
}
public class PonyRepository : IRepository<Pony>
{
IEnumerable<Pony> GetAll();
}
To actually supply me the data I need, I generally create a TestObjects or TestFakes class to supply the required data on-demand.
public class FakeStuff
{
public static IEnumerable<Pony> JustSomeGenericPonies(int numberOfPonies)
{
// return just some basic list
return new List<Pony>{new Pony{Colour = "Brown", Awesomeness = AwesomenessLevel.Max}};
// or could equally just go bananas in here and do stuff like...
var lOfP = new List<Pony>();
for(int i = 0; i < numberOfPonies; i++)
{
var p = new Pony();
if(i % 2 == 0)
{
p.Colour = "Gray";
}
else
{
p.Colour = "Orange";
}
lOfP.Add(p);
}
return lOfP;
}
}
And test with this as such:
[Test]
public void Hello_I_Want_to_test_ponies()
{
Mock<IRepository<Pony> _mockPonyRepo = new Mock<IRepository<Pony>>();
_mockPonyRepo.SetUp(m => m.GetAll()).Returns(FakeStuff.JustSomeGenericPonies(50));
// Do things that test using the repository
}
So this delivers reusability of the fake data, by keeping it out of the repository and in a place of it's own, meaning I can call this list of ponies anywhere a test requires a list of ponies, not just where a repository is involved.
If I need specific data for a specific testcase, i'll implement something like you had, but be a bit more explicit about what that particular Fake repository is for:
public class FakePonyRepositoryThatOnlyReturnsBrownPonies : IRepository<Pony>
{
private List<Pony> _verySpecificAndNotReusableListOfOnlyBrownPonies = new List....
public IEnumerable<Pony> GetAll()
{
return _verySpecificAndNotReusableListOfOnlyBrownPonies;
}
}
public class FakePonyRepositoryThatThrowsExceptionFromGetAll : IRepository<Pony>
{
public IEnumerable<Pony> GetAll()
{
throw new OmgNoPoniesException();
}
}
You mentioned CSV files as well - this could be viable (have used XML in the past), but I'd argue that holding fake data in a CSV or XML is just a worse version of keeping data in a localised DB using SQL CE or some equivalent. However, both of those are less maintainable and, crucially, in terms of unit tests, slower than using in-memory fake objects. I personally wouldn't use a file-based approach anymore unless I was specifically testing serialization or IO or something.
Hope there's something useful among all that lot...