2016-11-13 5 views
1

私はモジュール式の振る舞いを持つC#(.NET Coreベース)でチャットボットを開発しています。私が開発したい動作の1つは、(他の機能の中でも)管理者が他の動作を名前で動的に有効または無効にできるようにする "admin"モジュールです。Moqを使用してC#のモックの "タイプ名"を模倣することは可能ですか?

私はそのタイプの情報を検査し、何か行うことによって行動の名前を決定するために、管理モジュールをしたい:私はセットアップしようとしている、私が最初に書いているBDDの明細書では

var name = behaviour.GetType().GetTypeInfo().Name.Replace("Behaviour", string.Empty).ToLowerInvariant(); 

を管理モジュール(テスト中のシステム)とモックのふるまいからなる「行動チェーン」。このテストでは、管理モジュールに模擬動作を有効または無効にするコマンドを送信します。

これは私がこれまで何をやったかである:

式:

public BehaviourIsEnabled() : base("Admin requests that a behaviour is enabled") 
{ 
    var mockTypeInfo = new Mock<TypeInfo>(); 
    mockTypeInfo.SetupGet(it => it.Name).Returns("MockBehaviour"); 

    var mockType = new Mock<Type>(); 
    mockType.Setup(it => it.GetTypeInfo()).Returns(mockTypeInfo.Object); 

    // TODO: make mock behaviour respond to "foo" 
    var mockBehaviour = new Mock<IMofichanBehaviour>(); 
    mockBehaviour.Setup(b => b.GetType()).Returns(mockType.Object); 

    this.Given(s => s.Given_Mofichan_is_configured_with_behaviour("administration"), AddBehaviourTemplate) 
     .Given(s => s.Given_Mofichan_is_configured_with_behaviour(mockBehaviour.Object), 
       "Given Mofichan is configured with a mock behaviour") 
      .And(s => s.Given_Mofichan_is_running()) 
     .When(s => s.When_I_request_that_a_behaviour_is_enabled("mock")) 
      .And(s => s.When_Mofichan_receives_a_message(this.JohnSmithUser, "foo")) 
     .Then(s => s.Then_the_mock_behaviour_should_have_been_triggered()) 
     .TearDownWith(s => s.TearDown()); 
} 

問題、私はこれを実行すると部品番号が例外をスローしてGetTypeInfo()は、Typeに拡張メソッドであるということです模倣された オブジェクトに属していないメソッドを参照します:it => it.GetTypeInfo()

別の方法として、プロパティをIMofichanBehaviourに追加することもできますが、テストコードのために実際に存在するプロダクションコードに任意のメソッド/プロパティを追加することは嫌いです。

+0

ようになりますが、拡張メソッドを表示します。拡張メソッド(静的)は、メソッドの複雑さや、テスト容易性のために静的なクラスやメソッドを避けなければならないという事実だけでは、テストが困難になります。 – Nkosi

+0

@ Nkosi拡張メソッドを表示するとどういう意味ですか?私はポストでそれを与えた:['GetTypeInfo()'](https://msdn.microsoft.com/en-us/library/system.reflection.introspectionextensions.gettypeinfo(v = vs.110).aspx) 。拡張/静的メソッドは避けるのがよいと思いますが、この場合.NET Coreの型情報を検査するために使用するビルトインメソッドのように多くの選択肢がありません。 – Tagc

+1

次に、偽の 'public class MockBehaviour:IMofichanBehaviour {...}' – Nkosi

答えて

1

模倣されているものを満たす偽のクラスで簡単にしてください。

public class MockBehaviour : IMofichanBehaviour { ... } 

、テストが、その後

public BehaviourIsEnabled() : base("Admin requests that a behaviour is enabled") { 

    // TODO: make mock behaviour respond to "foo" 
    var mockBehaviour = new MockBehaviour(); 


    this.Given(s => s.Given_Mofichan_is_configured_with_behaviour("administration"), AddBehaviourTemplate) 
     .Given(s => s.Given_Mofichan_is_configured_with_behaviour(mockBehaviour), 
       "Given Mofichan is configured with a mock behaviour") 
      .And(s => s.Given_Mofichan_is_running()) 
     .When(s => s.When_I_request_that_a_behaviour_is_enabled("mock")) 
      .And(s => s.When_Mofichan_receives_a_message(this.JohnSmithUser, "foo")) 
     .Then(s => s.Then_the_mock_behaviour_should_have_been_triggered()) 
     .TearDownWith(s => s.TearDown()); 
} 
+0

+1を使用します。これは単純ですが効果的です。私は自分自身でそれを考えなかったことに夢見ています。先に "Name/Id"アイデアを検討していましたが、実際にそのルートを下ってしまっていますが、この動作が必要な場合は、これを覚えておいてください。誰かがMoqで型情報を模倣する方法を投稿しない限り、やはり受け入れられるが、これはやや便利だが決して必須ではない。 – Tagc

関連する問題