जब तक आपके Bus
चर के रूप में एक IBus
उदाहरण है, तो आप बस वर्ग है कि इस विधि में शामिल करने के लिए एक मज़ाक उड़ाया IBus
कार्यान्वयन प्रदान कर सकते हैं, और (, उचित प्रतिनिधि के साथ अगर आप ऐसा चाहते हैं) सत्यापित करें कि संदेश उस पर बुलाया गया था परीक्षण के लिए विधि लागू करने के बाद। इसके अलावा, आप Bus.Send
स्वयं परीक्षण कर रहे हैं, जो ऐसा कुछ नहीं है जो आपको करना चाहिए।
public class ClassThatSendsMessages
{
private readonly IBus _bus;
public ClassThatSendsMessages(IBus bus /*, ... */)
{
_bus = bus;
/* ... */
}
public void CodeThatSendsMessage()
{
/* ... */
_bus.Send<IMyMessage>(mm => mm.Property1 = "123");
/* ... */
}
}
public class ClassThatTestsClassThatSendsMessages
{
public void CallCodeThatSendsMessage()
{
//Mock IBus object here
var objectToTest = new ClassThatSendsMessages(mockedIBus /*, ... */)
objectToTest.CodeThatSendsMessage();
//Verify that IBus mock's Send() method was called
}
}
वहाँ प्रतिनिधि के तर्क का परीक्षण दृष्टिकोण दो तरीके हैं: आप, बशर्ते अभिव्यक्ति पेड़ को तोड़ने की कोशिश कर सकते हैं या आप एक नामित विधि करने के लिए इसे बदल सकते हैं और इसे उस तरह से पारित कर सकते हैं। मैं भाव में गहरी मिल गया कभी नहीं किया है, तो मैं बाद का एक उदाहरण प्रदान करेंगे:
public static class MyMessageBuilder
{
public static void Build(IMyMessage message) { /* ... */ }
}
public class ClassThatTestsMyMessageBuilder
{
public void CallCodeThatBuildsMessage()
{
var message = Test.CreateInstance<IMyMessage>(MyMessageBuilder.Build);
//Verify message contents
}
}
उपयोग:
public class ClassThatSendsMessages
{
private readonly IBus _bus;
public static Action<IMyMessage> BuildMessage { private get; set; }
public ClassThatSendsMessages(IBus bus /*, ... */)
{
_bus = bus;
/* ... */
}
public void CodeThatSendsMessage()
{
/* ... */
_bus.Send<IMyMessage>(mm => BuildMessage (mm));
/* ... */
}
}
मैं एक कंटेनर है कि करने के लिए प्रतिनिधि इंजेक्शन कर सकते हैं के बारे में पता नहीं कर रहा हूँ रचनाकार, लेकिन फिर मैंने बहुत मुश्किल नहीं देखा है, ताकि प्रतिनिधि को स्थापित करने का एक बेहतर तरीका हो।
संपादित
मैं हाल ही में मेरे अपने परीक्षण में इस मुद्दे में चलाने की है, और मैं वास्तव में अपने स्वयं के निर्माता में विधि बाहर निकलने के लिए होने की तरह नहीं है। इसलिए मैंने यह पता लगाने के लिए तैयार किया कि क्या मैं "जगह में" प्रतिनिधि का परीक्षण कर सकता हूं। यह पता चला है कि आप कर सकते हैं:
public class ClassThatTestsClassThatSendsMessages
{
public void CallCodeThatSendsMessage()
{
Action<IMyMessage> messageAction = null;
//Mock IBus object here
mockedIBus.Setup(b => b.Send(Args.IsAny<Action<IMyMessage>>()))
.Callback((Action<IMyMessage> a) => messageAction = a);
var myMessage = Test.CreateInstance<IMyMessage>();
var objectToTest = new ClassThatSendsMessages(mockedIBus /*, ... */)
//Run the code that sends the message
objectToTest.CodeThatSendsMessage();
//Run the code that populates the message
messageAction(myMessage);
//Verify expectations on Setups
//Verify the message contents;
}
}
वहाँ समझौतों से यहाँ हैं - निश्चित रूप से एक इनलाइन प्रतिनिधि के रूप में इसे छोड़ने से SRP के साथ और अधिक आज्ञाकारी संदेश बिल्डर एक इंटरफ़ेस में बाहर खींच रहा है (परीक्षण के रूप में स्पष्ट रूप से दर्शाता है: क्या आप करने के लिए है सभी कोड का परीक्षण करने के लिए दो बार कार्य करें)। हालांकि, यह कोड आकार और पठनीयता दोनों में लाभ प्रस्तुत करता है।
इसके अतिरिक्त, यह कोड Moq-specific है; मुझे नहीं पता कि प्रतिनिधि को राइनोमोक्स मॉक से वापस लेना संभव है या उसके लिए सिंटैक्स क्या होगा।
क्या आप 'Bus.Send', या कोड भेजने वाले कोड के बारे में पूछ रहे हैं? – arootbeer
arootbeer, मैं संदेश भेजने वाले कोड के बारे में पूछ रहा हूं। मैं जिस सटीक कोड का परीक्षण करना चाहता हूं वह ऊपर दिए गए प्रश्न में दिया गया है। – mgamer
मैंने रुचि रखने वाले मामले में प्रतिनिधि कोड को स्थानांतरित करने के संबंध में एक संपादन जोड़ा। – arootbeer