7

我正在努力在我们的服务中实现 AutoMapper,并且在我们的单元测试中看到了一个非常令人困惑的问题。

首先,这个问题涉及以下对象及其各自的地图:

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

它还涉及这些对象,尽管此时我还没有使用 AutoMapper 映射这些对象:

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; }
}

这些类使用包含以下内容的自定义代码进行转换,其中source是 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);
} 

我遇到问题的测试创建了一个新的 DbParty,2 个新的 DbAccounts 链接到新的 DbParty,2 个新的 DbPartyAccountRoles 都链接到新的 DbParty,每个 DbAccounts 各有 1 个。然后它通过 DbParty 存储库测试一些更新功能。如果需要,我可以为此包含一些代码,它只需要一些时间来清理。

当它自己运行时,这个测试工作得很好,但是当在与另一个测试相同的会话中运行时(我将在下面详细说明),上述转换代码中的 Mapper 调用会抛出这个异常:

System.InvalidCastException : Unable to cast object of type '[Namespace].Account' to type '[Namespace].LazyAccount'.

另一个测试还创建了一个新的 DbParty,但只有一个 DbAccount,然后创建了 3 个 DbPartyAccountRoles。我能够将这个测试缩小到打破另一个测试的确切行,它是:

Assert.That(DbPartyAccountRole.FindAll().Count(), Is.EqualTo(3))

注释掉这一行允许其他测试通过。

有了这些信息,我的猜测是测试正在中断,因为调用 AutoMapper 时与 DbAccount 对象后面的 CastleProxy 有关,但我对如何操作一无所知。

我现在已经设法运行相关的功能测试(对服务本身进行调用)并且它们似乎工作正常,这让我认为单元测试设置可能是一个因素,最值得注意的是有问题的测试是针对内存数据库中的 SqlLite。

4

1 回答 1

0

该问题最终与在单元测试中多次运行 AutoMapper Bootstrapper 有关;调用在我们的测试基类的 TestFixtureSetup 方法中。

修复是在创建地图之前添加以下行:

Mapper.Reset();

我仍然很好奇为什么这是唯一有问题的地图。

于 2015-09-09T23:33:15.687 回答