2009-04-22 6 views
2

これをデバッグしようとすると、私の髪の毛を引き出します。今朝早く、このコードはうまくいきました。私はそれを打破するために何を変えたのか分かりません。私はNHibernateはセッションを開こうとする時はいつでも今、私は次のエラーを取得しています:System.TypeInitializationException:nHibernate/RhinoMocks TypeInitializer例外をデバッグする方法

試験方法BCMS.Tests.Repositories.BlogBlogRepositoryTests.can_get_recent_blog_postsは、例外をスローしたタイプ初期化子をNHibernate.Cfg」のため。環境」は例外を投げた。 ---> System.Runtime.Serialization.SerializationException:型がメンバ 'Castle.DynamicProxy.Serialization.ProxyObjectReference、Rhino.Mocks、Version = 3.5.0.1337、Culture = neutral、PublicKeyToken = 0b3305902db7183f'で解決されていません..

ここで何が起こっているのかをデバッグする方法はありますか?

+0

あなたはコードの一部を持っていますか? –

答えて

1

さらに詳しい情報... Thread.CurrentPrincipalを模倣したIPrincipal実装に切り替えることに関連しているようです。エンティティ内のドメインモデルですべてのセキュリティチェックを行います。エンティティのメソッドは、エンティティのプロパティを変更する前にThread.CurrentPrincipal.IsInRole()をチェックします。

エンティティのメソッドをテストするには、エンティティメソッドを呼び出す前に別のユーザー(コントリビュータのユーザー、モデレータのユーザーなど)を設定する必要があります。

昨日なぜこれが正常に機能していたのか分かりませんでした。ここで

は私の嘲笑IPrincipalの例を示します。このような

 private static IPrincipal _blogContributorUser = null; 
    public static IPrincipal BlogContributorUser 
    { 
     get 
     { 
      if (null == _blogContributorUser) 
      { 
       var identity = MockRepository.GenerateStub<IIdentity>(); 
       identity.Stub(p => p.Name).Return("BlogContributor").Repeat.Any(); 
       var principal = MockRepository.GenerateStub<IPrincipal>(); 
       principal.Stub(p => p.Identity).Return(identity).Repeat.Any(); 
       principal.Stub(p => p.IsInRole(UserRoles.BlogContributor)).Return(true).Repeat.Any(); 
       principal.Stub(p => p.IsInRole(UserRoles.CommentContributor)).Return(true).Repeat.Any(); 
       principal.Stub(p => p.IsInRole(UserRoles.TagContributor)).Return(true).Repeat.Any(); 
       _blogContributorUser = principal; 
      } 
      return _blogContributorUser; 
     } 
    } 
1

エラーは通常、バージョン管理の問題を示しています。

私は、RhinoMockとNHibernateの両方がCastle.DynamicProxy型を使用していると考えていますが、それらの型の異なるバージョンを求めています。

最近RhinoMockやNHibernateを新しいバージョンにアップグレードしましたか?

これが問題でない場合は、より多くの情報が役立ちます。すべてのテストが失敗するか、この特定のテストのみが失敗しますか?また、あなたのプロパティ\ AssemblyInfo.csファイルに次の行を追加してみたいことがあり

編集:

[assembly: InternalsVisibleTo("Rhino.Mocks")] 
[assembly: InternalsVisibleTo("Castle.DynamicProxy")] 
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")] 
0

は、私は同じ問題を持っています。 CurrentPrincipalが変更されているので、configファイルの読み込みに問題があるようです。 CurrentPrincipal(例えば、開いたNHibernateセッション、初期化されたUnityやそのような種類のもの)を置き換える前に、設定ファイルから初期化する必要があるすべてを移動しました。もちろん、これは解決策ではありません。絶望的な人間によって理解された回避策です。

2

私はあなたと同じ問題を打つ - 私の場合それはNLogの静的メソッドとあった:

LogManager.GetCurrentClassLogger() 

私はRhinomocksスタブと現在のスレッドのプリンシパルを交換したい:

var identity = MockRepository.GenerateStub<IIdentity>(); 
identity.Stub(x => x.IsAuthenticated).Return(true); 
var principal = MockRepository.GenerateStub<IPrincipal>(); 
principal.Stub(x => x.Identity).Return(identity); 
Thread.CurrentPrincipal = principal; 

ランニング私のコードの単体テストは、元の質問と同じ例外を投げた。

スタックトレース:あなたは動作しません作られて設定ファイルを読み込むしようとし、スタックトレースから見ることができるように

at System.AppDomain.get_Evidence() 
at System.AppDomain.get_EvidenceNoDemand() 
at System.AppDomain.get_Evidence() 
at System.Configuration.ClientConfigPaths.GetEvidenceInfo(AppDomain appDomain, String exePath, String& typeName) 
at System.Configuration.ClientConfigPaths.GetTypeAndHashSuffix(AppDomain appDomain, String exePath) 
at System.Configuration.ClientConfigPaths..ctor(String exePath, Boolean includeUserConfig) 
at System.Configuration.ClientConfigPaths.GetPaths(String exePath, Boolean includeUserConfig) 
at System.Configuration.ClientConfigurationHost.RequireCompleteInit(IInternalConfigRecord record) 
at System.Configuration.BaseConfigurationRecord.GetSectionRecursive(String configKey, Boolean getLkg, Boolean checkPermission, Boolean getRuntimeObject, Boolean requestIsHere, Object& result, Object& resultRuntimeObject) 
at System.Configuration.BaseConfigurationRecord.GetSection(String configKey) 
at System.Configuration.ClientConfigurationSystem.System.Configuration.Internal.IInternalConfigSystem.GetSection(String sectionName) 
at System.Configuration.ConfigurationManager.GetSection(String sectionName) 
at NLog.Config.XmlLoggingConfiguration.get_AppConfig() 
at NLog.LogFactory.get_Configuration() 
at NLog.LogFactory.GetLogger(LoggerCacheKey cacheKey) 
at NLog.LogFactory.GetLogger(String name) 
at NLog.LogManager.GetCurrentClassLogger() 
at MyClassHere... 

- なぜ?現在の嘲笑された現在のプリンシパルは、もともとは私たちが持っていたWindowsPrincipalではなくなったため、Windowsのファイルアクセスを一切持たない偽のプリンシパルになりました。

ここでは、この問題を解決するための方法がいくつかあります。

  1. ロガーをスタブにするために、私のクラスにロガーを注入してください(とにかく私はこれをやっているはずです)。これにより、スレッドのプリンシパルにスタブを使用することができます。
  2. スレッドで、既存のWindowsPrincipalを変更(またはそれに基づいて別のスレッドを作成)して、自分のメソッドを呼び出すために必要なロールを追加します。

- UPDATE -

私の問題を解決するには、最後に私は上記の私の最初の提案で実行することを決めました。私自身のNLog Loggerの抽象化を避けるために、私はCommon.Loggingから提供されたものを活用しました。クラスのコンストラクタは現在ロガーがちょうどこのように見える注入するそれらのパラメータの一つとしてのILog、ユニティ設定を受け入れる:

container.RegisterType<ILog>(new TransientLifetimeManager(), new InjectionFactory(x => LogManager.GetCurrentClassLogger())); 

はまた、私のユニットテストは、今私が嘲笑ロガーに渡すことができます。

var logger = MockRepository.GenerateStub<ILog>(); 
0

エラーが解決RhinoMocksまたは部品番号とIPrincipalおよび/またはIIdentityをあざけるに関連している場合は、実際には非常に簡単です:これらのフレームワークを使用する代わりに、単純な偽の種類を作成しないでください。あなたはSystem.Security.Principal.GenericPrincipalクラスを見てより多くの複雑さを必要とする場合は

public class FakeIdentity : IIdentity 
{ 
    public string Name { get { return "IntegrationTest"; } } 

    public string AuthenticationType { get { return "Kerberos"; } } 

    public bool IsAuthenticated { get { return true; } } 
} 

public class FakePrincipal : IPrincipal 
{ 
    public FakePrincipal() { this.Identity = new FakeIdentity(); } 

    public IIdentity Identity { get; private set; } 

    public bool IsInRole(string role) { return true; } 
} 

:ここ

は簡単な実装、「すべて許可」の一例です。

関連する問題