我創建了一個類,SenderClass
,它將從其構造函數啓動並運行後臺工作。 方法RunWorker()
的運行是一個while(true)
循環,它將從隊列中彈出元素,通過方法SendMessage()
發送它們,並休眠一段時間以允許將新元素添加到隊列中。單元測試後臺線程與接口
問題在於如何測試從隊列中發送元素而不將它暴露給使用該類的人的方法?
實現:
public class SenderClass : ISenderClass
{
private Queue<int> _myQueue = new Queue<int>();
private Thread _worker;
public SenderClass()
{
//Create a background worker
_worker = new Thread(RunWorker) {IsBackground = true};
_worker.Start();
}
private void RunWorker() //This is the background worker's method
{
while (true) //Keep it running
{
lock (_myQueue) //No fiddling from other threads
{
while (_myQueue.Count != 0) //Pop elements if found
SendMessage(_myQueue.Dequeue()); //Send the element
}
Thread.Sleep(50); //Allow new elements to be inserted
}
}
private void SendMessage(int element)
{
//This is what we want to test
}
public void AddToQueue(int element)
{
Task.Run(() => //Async method will return at ones, not slowing the caller
{
lock (_myQueue) //Lock queue to insert into it
{
_myQueue.Enqueue(element);
}
});
}
}
通緝接口:
public interface ISenderClass
{
void AddToQueue(int element);
}
所需接口,用於測試目的:
public interface ISenderClass
{
void SendMessage(int element);
void AddToQueue(int element);
}
有一個非常簡單的解決方案,說我創造了我的課不正確由於到Single Responsability Principle,我班的目的不是發送消息,而是實現盟友運行發送它們的東西。
我應該有的是另一個類TransmittingClass
,它通過自己的接口公開方法SendMessage(int)
。 這樣我可以測試該類,SenderClass
應該只是通過該接口調用該方法。
但我還有什麼其他選擇與當前的實施?
我可以使我想測試的所有私有方法(所有這些方法)都有[assembly:InternalsVisibleTo("MyTests")]
,但是是否存在第三個選項?
假設爲了測試的目的你暴露了'SendMessage',你會如何測試它?你不會簡單地通過在別的地方收到郵件來檢查郵件是否被髮送了嗎? – Kenney
發送消息邏輯應該在具有單獨接口的單獨類中實現。這個類應該把新類作爲依賴。你可以單獨測試其他類。 – axlj
我補充說,作爲解決方案@axlj - 謝謝。 –