gpt4 book ai didi

c# - 异步 TDD - 测试类 block

转载 作者:太空宇宙 更新时间:2023-11-03 14:26:15 25 4
gpt4 key购买 nike

如何创建单元测试来测试循环中的类?

这是场景。

我有一个注入(inject)了对串行端口的引用的类。

该类有一个名为 Send(String data) 的方法;

此公共(public)方法调用异步私有(private)方法来完成实际工作。

调用此方法时,被测类 (CUT) 应执行以下操作。

1) 将字符串拆分为字符。
2) 发送一个字符
3) 等待字符被回显
4) 发送下一个字符(重复直到发送完所有字符)

因此在发送第一个字符后,CUT 将进入一个循环等待回显,直到它收到一个回显或超时。

我遇到的问题是,一旦 CUT 进入此循环,它将阻塞测试类,直到超时。

因为我需要测试类将回显发送到我卡住的 CUT。

为了对此进行测试,我创建了一个模拟串行端口并使用 NUnit。

测试如下。这个想法是,在发送测试字符串后,我等待 CUT 响应。每次 CUT 将一个字符写入串行端口时,等待都会被取消,我会向串行端口写入一个回显,CUT 通过发送下一个字符对此做出响应。

    [Test]
public void Test()
{
_serialPort.DataSentEvent += new EventHandler(_serialPort_DataSentEvent);

_completedSync = new ManualResetEvent(false);

_wrapperPort.Send("TEST");

_completedSync.WaitOne(1000); // wait for first char

Assert.AreEqual("T", _serialPort.BufferOUT); //first char sent

_serialPort.BufferIN = "T"; //write the echo

_completedSync.WaitOne(1000); //wait for second char

Assert.AreEqual("E", _serialPort.BufferOUT); //second char sent

//...etc
}

void _serialPort_DataSentEvent(object sender, EventArgs e)
{
_completedSync.Set();
}

但是,一旦调用 Send("TEST"),CUT 就会阻塞,并且只有在 CUT 等待回显超时后,控制才会返回到测试类。

既然 Send 方法正在另一个线程上完成,为什么它会阻塞测试类?

最佳答案

我认为您在测试中混入了太多实现细节。

您已经非常精确地指定了串口协议(protocol),所以我将定义一个描述该协议(protocol)的接口(interface):

public interface ISerialPort
{
event EventHandler Echo;

void Send(char c);
}

此界面强制我一次发送一个字符。当正确使用此接口(interface)时,串行端口包装器将正常工作。 这种方法需要一个额外的真实串口包装器类。正是这个类需要处理异步操作才能正确实现接口(interface)。

使用 TestSerialPort,我可以按如下方式编写测试:

    [TestMethod]
public void Send_data_as_chars_to_serial_port()
{
const string data = "TEST";
var serialPort = new TestSerialPort();
var wrapperPort = new WrapperPort(serialPort);

wrapperPort.Send(data);

Assert.AreEqual(data, serialPort.Buffer);
Assert.AreEqual(data.Length, serialPort.SendCount);
}

TestSerialPort 实现接口(interface),模拟真实的串口行为,并公开测试可以断言的数据:

public class TestSerialPort : ISerialPort
{
public string Buffer;
public int SendCount;

public void Send(char c)
{
SendCount++;
Buffer += c;
Echo.Invoke(this, EventArgs.Empty);
}

public event EventHandler Echo;
}

满足上述测试的一种可能实现方式:

public class WrapperPort
{
private readonly ISerialPort serialPort;
private Queue<char> buffer;
private char current;

public WrapperPort(ISerialPort serialPort)
{
this.serialPort = serialPort;
serialPort.Echo += OnEcho;
}

public void Send(string data)
{
buffer = new Queue<char>(data);
SendNextCharacter();
}

private void OnEcho(object sender, EventArgs e)
{
SendNextCharacter();
}

private void SendNextCharacter()
{
if (buffer.Any() == false) return;
current = buffer.Dequeue();
serialPort.Send(current);
}
}

关于c# - 异步 TDD - 测试类 block ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3880611/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com