问题
I am working on implementing AutoMapper in our service and am seeing a very confusing issue in our unit tests.
First off this issue involves the following objects and their respective maps:
public class DbAccount : ActiveRecordBase<DbAccount>
{
// this is the ORM entity
}
public class Account
{
// this is the primary full valued Dto
}
public class LazyAccount : Account
{
// this class as it is named doesn't load the majority of the properties of account
}
Mapper.CreateMap<DbAccount,Account>();
//There are lots of custom mappings, but I don't believe they are relevant
Mapper.CreateMap<DbAccount,LazyAccount>();
//All non matched properties are ignored
It also involves these objects, though I haven't mapped these with AutoMapper at this point:
public class DbParty : ActiveRecordBase<DbParty>
{
public IList<DbPartyAccountRole> PartyAccountRoles { get; set; }
public IList<DbAccount> Accounts {get; set;}
}
public class DbPartyAccountRole : ActiveRecordBase<DbPartyAccountRole>
{
public DbParty Party { get; set; }
public DbAccount Account { get; set; }
}
These classes are converted using custom code that includes the following, where source
is a DbParty:
var party = new Party()
//field to field mapping here
foreach (var partyAccountRole in source.PartyAccountRoles)
{
var account = Mapper.Map<LazyAccount>(partyAccountRole.Account);
account.Party = party;
party.Accounts.Add(account);
}
The test I'm having an issue with creates a new DbParty, 2 new DbAccounts linked to the new DbParty, and 2 new DbPartyAccountRoles both linked to the new DbParty and 1 each to each of the DbAccounts. It then tests some update functionality via the DbParty repository. I can include some code for this if needed it will just take some time to scrub.
When run by itself this test works just fine, but when run in the same session as another test (that I will detail below) the Mapper call in the above conversion code throws this exception:
System.InvalidCastException : Unable to cast object of type '[Namespace].Account' to type '[Namespace].LazyAccount'.
The other test also creates a new DbParty but with only one DbAccount and then creates 3 DbPartyAccountRoles. I was able to narrow this test down to the exact line that breaks the other test and it is:
Assert.That(DbPartyAccountRole.FindAll().Count(), Is.EqualTo(3))
Commenting out this line allows the other test to pass.
With that information my guess is that the test is breaking because of something to do with the CastleProxy that is behind the DbAccount object when calling AutoMapper but I don't have the slightest idea of how.
I've now managed to run the relevant functional tests (making calls against the service itself) and they seem to work fine, this makes me think the unit test setup may be a factor, most notable is that the tests in question are run against a SqlLite in memory database.
回答1:
The problem ended up being related to running the AutoMapper Bootstrapper multiple times in the unit tests; the invocation was in the TestFixtureSetup method on our testing base class.
The fix was to add the following line before creating the maps:
Mapper.Reset();
I am still curious as to why this was the only map that had an issue.
来源:https://stackoverflow.com/questions/32489127/how-to-stop-automapper-from-mapping-to-parent-class-when-child-class-was-request