2

Currently in a part of my project a domain object like below exists:

public class Address
{
    public virtual string HouseName { get; set; }

    public virtual string HouseNumber { get; set; }

    public virtual string RoadName { get; set; }

    public virtual string Postcode { get; set; }

    public virtual string District { get; private set; }
}

The District property is a calculated column in the database. Due to the requirements of the data access provider (Entity Framework) a private set is required. This is fine in normal program flow as the District never needs to be set, due to it being updated when an Address record is saved/updated in the database

A method that I want to test looks like this:

public IEnumerable<House> GetHousesWithinSameDistrict (int addressId)
{
    var addressToMatch = _addressRepository.FirstOrDefault(address => address.Id == addressId)

    return _houseRepository.Where(house => house.Address.District == addressToMatch.District)
}

This is causing me problems when I try to set up the addressToMatch variable, as I am unable to set the District property and as such I cannot write a test to check correct matching addresses are returned.

How should I go about setting up an Address object for this test?

1

Your method GetHousesWithinSameDistrict makes use of a house repository, and an address repository, and has its own logic to select amongst the entities returned by these repositories. As such I would suggest the simple solution is to make use of mocking, and mock those repositories to return entities of the appropriate type, such that you can test your various scenarios.

Furthermore, can you return via your mocks some dummy entities that simply implement suitable interfaces ? e.g. your sample code simply requires address ids and districts. Consequently your functionality that you need to test simply needs objects that talk in those terms, and not fully functional objects populated via the database.

  • Your firs paragraph is exactly what I'm trying to do, however I'm unable to mock an object to return as I can't populate the District property. – FLSH Apr 29 '16 at 12:55
  • Can't you configure your mock as returning a further set of mocked objects ? Those mocked objects would be set up with districts. Or, just return objects adhering to the same interface (with District fields) that aren't your specific entity objects – Brian Agnew Apr 29 '16 at 12:57
1

Here's an example that I'm doing to Fake the Id property of my entity.

        A.CallTo(() => _fakeRepository.FindAll()).Returns((new List<HighSchoolType>()).AsQueryable());
        Guid fakePublicHighSchoolId = Guid.NewGuid();
        var fakePublicHighSchool = A.Fake<HighSchoolType>();
        A.CallTo(() => fakePublicHighSchool.Id).Returns(fakePublicHighSchoolId);

So fake the repository, then fake the entity coming back and fake the property that you want to return.

it's fakes all the way down.

This example is using FakeItEasy.

0

The simple answer is: use reflection. For example, the following code creates an Address object and sets District:

var address = new Address();
typeof(Address).GetProperty("District").SetValue(address, "A district", null);

How you do that in your test code depends on what _addressRepository is (eg, is it declared as an interface?) and how easily it is mocked to supply test data.

(And this question really should have been asked on Stack Overflow, rather than here).

  • This was my first port of call as it's worked for me before, however it does not work in my case. If I change the property to protected set instead then it works, but that's not a solution. I know it seems a bit too specific for programmers but I purposefully left the question vague as it feels there is something wrong with my test pattern. – FLSH Apr 29 '16 at 12:29
  • @FLSH, If reflection doesn't work, then you have run into app domain trust issues, which unfortunately is beyond my knowledge. There seems nothing wrong with your test pattern, so I'd still advise asking on SO, where people with more EF knowledge than myself can probably give you a proper answer. – David Arno Apr 29 '16 at 12:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.