環境:NUnit的2.6.4; NUnit TestAdapter 2.0.0; Moq 4.2.1; VisualStudio 4.6;C#模擬測試 - 起訂量清單不可能 '的foreach' 告訴 '的NullReferenceException'
簡介: 我implemet在具有供應商的傳感器,報警,PowerSuply,顯示器的接口HomeSecuritySystem。我想測試它的實現。我想測試'SystemCheckPass'子例程。
我嘲笑的iSensor的列表,並構建「SecurityController」,然後我跑「SystemCheckPass」子程序。當它執行到'SystemCheckPass'子例程時,'foreach'不能正常運行,它說'NullReferenceException'。
它是在對ISensors的MockList了「的foreach」循環測試功能都很好。在簡單地將ref傳遞給'SecurityController'之後,'list'的'foreach''loop'找不到它的元素的'ref'。我對此很困惑。
有人能告訴我爲什麼嗎?
實施安全控制器。
using System;
using System.Collections.Generic;
using HomeSecuritySystem.Sensors;
using HomeSecuritySystem.Comms;
using HomeSecuritySystem.Power;
using HomeSecuritySystem.Display;
using HomeSecuritySystem.Alarm;
using HomeSecuritySystem.Report;
using System.Threading;
using System.Diagnostics;
namespace HomeSecuritySystem
{
public class SecurityController : ControllerBase
{
public int Value;
public ICollection<ISensor> sensors;
public IComms comms;
public IPowerSupply powerSupply;
public IAlarm alarm;
public IDisplay display;
public SecurityController(ICollection<ISensor> sensors, IComms comms, IPowerSupply powerSupply, IAlarm alarm, IDisplay display)
: base(sensors, comms, powerSupply, alarm, display)
{
this.sensors = sensors;
this.comms = comms;
this.powerSupply = powerSupply;
this.alarm = alarm;
this.display = display;
// bind the power down event when system initials, because it never changes.
powerSupply.OnNoPower += new Events.NoPowerEvent(PowerSupplyNoPower);
// initialize
IsArmedLastSate = IsArmed;
IsStayLastSate = IsStay;
}
public bool SystemCheckPass()
{
// <---- begin system check
bool systemCheckPass = true;
// check the device power except sensors
if (alarm.IsOn == false || comms.IsOn == false || powerSupply.IsOn == false)
{
// part of system check, power is off, system check fail
systemCheckPass = false;
}
// check power of sensors
foreach (ISensor sensor in sensors)
{
if (sensor.IsOn == false)
systemCheckPass = false;
}
/*
// check the battery of sensors
foreach (ISensor sensor in sensors)
{
switch (sensor.Type)
{
// part of system check, motion sensor's battery is low, system check fail
case Report.SensorType.Motion:
IMotionSensor motionSensor = (IMotionSensor)(sensor);
if (motionSensor.IsLowBattery == true)
{
systemCheckPass = false;
}
break;
// part of system check, smoke sensor's battery is low, system check fail
case Report.SensorType.Smoke:
ISmokeSensor smokeSensor = (ISmokeSensor)(sensor);
if (smokeSensor.IsLowBattery == true)
{
systemCheckPass = false;
}
break;
default:
// so far, only two kinds of sensors
throw new Exception("no exit sensor type!");
}
}
//check the battery of power supply
if (powerSupply.IsLowBattery)
{
systemCheckPass = false;
}
*/
// system check over ---->
return systemCheckPass;
}
public override void SystemCheck()
{
// <---- begin system check
bool systemCheckPass = true;
List<int> lowBatterySensorIDList = new List<int>();
// check the device power except sensors
if (alarm.IsOn == false || comms.IsOn == false || powerSupply.IsOn == false)
{
// part of system check, power is off, system check fail
systemCheckPass = false;
}
// check power of sensors
foreach (ISensor sensor in sensors)
{
if (sensor.IsOn == false)
systemCheckPass = false;
}
bool lowBatterySensorExist = false;
// check the battery of sensors
foreach (ISensor sensor in sensors)
{
switch (sensor.Type)
{
// part of system check, motion sensor's battery is low, system check fail
case Report.SensorType.Motion:
IMotionSensor motionSensor = (IMotionSensor)(sensor);
if (motionSensor.IsLowBattery == true)
{
lowBatterySensorIDList.Add(motionSensor.Id);
systemCheckPass = false;
lowBatterySensorExist = true;
}
break;
// part of system check, smoke sensor's battery is low, system check fail
case Report.SensorType.Smoke:
ISmokeSensor smokeSensor = (ISmokeSensor)(sensor);
if (smokeSensor.IsLowBattery == true)
{
lowBatterySensorIDList.Add(smokeSensor.Id);
systemCheckPass = false;
lowBatterySensorExist = true;
}
break;
default:
// so far, only two kinds of sensors
throw new Exception("no exit sensor type!");
}
}
//check the battery of power supply
bool BatteryOfPowSupplyIsLow = false;
if (powerSupply.IsLowBattery)
{
systemCheckPass = false;
BatteryOfPowSupplyIsLow = true;
}
// system check over ---->
// <---- report begin
if (systemCheckPass)
{
display.ShowSystemReady();
}
else
{
display.ShowSystemNotReady();
}
if (lowBatterySensorExist)
{
display.ShowSensorLowBattery(lowBatterySensorIDList);
}
if (BatteryOfPowSupplyIsLow)
{
display.ShowPowerSupplyLowBattery();
}
// report end --->
}
public override void ClearMemory()
{
display.ClearSentReport();
display.ClearAlarmSound();
display.ClearSystemArmed();
foreach (ISensor sensor in sensors)
{
display.ClearSensorDetected(sensor.Id);
}
}
// bind to event sensor.OnDetectionStateChanged
public void ArmSensorDetected(ISensor sensor)
{
if (sensor.Detected)
{
alarm.SoundAlarm();
display.ShowAlarmSound();
display.ShowSensorDetected(sensor.Id);
Report.Report report = new Report.Report();
report.SensorId = sensor.Id;
report.SensorType = sensor.Type;
report.Time = new DateTime();
report.Type = Report.ReportType.Intrusion;
display.ShowSentReport("sensor detected");
comms.InformSecurity("sensor detected");
}
}
public void ArmStaySensorDetected(ISensor sensor)
{
if (sensor.Type == Report.SensorType.Motion)
{
IMotionSensor motionSensor = (IMotionSensor)(sensor);
if (motionSensor.Detected && motionSensor.IsPerimeterSensor)
{
alarm.SoundAlarm();
display.ShowAlarmSound();
display.ShowSensorDetected(sensor.Id);
display.ShowSentReport("sensor detected");
comms.InformSecurity("sensor detected");
}
}
}
public void SmokeSensorDetected(ISensor sensor)
{
if (sensor.Type == Report.SensorType.Smoke)
{
ISmokeSensor smokeSensor = (ISmokeSensor)(sensor);
if (smokeSensor.Detected)
{
Report.Report report = new Report.Report();
report.SensorId = sensor.Id;
report.SensorType = sensor.Type;
report.Time = new DateTime();
report.Type = Report.ReportType.Smoke;
alarm.SoundAlarm();
display.ShowAlarmSound();
display.ShowSensorDetected(sensor.Id);
display.ShowSentReport("sensor detected");
comms.InformSecurity("sensor detected");
}
}
}
public void PowerSupplyNoPower()
{
Report.Report report = new Report.Report();
report.Time = new DateTime();
report.Type = Report.ReportType.NoPower;
comms.InformSecurity("power down");
display.ShowSentReport("power down");
}
private bool IsArmedLastSate;
private bool IsStayLastSate;
private void DelegateHandling()
{
foreach (ISensor sensor in sensors)
{
sensor.OnDetectionStateChanged += new Events.SensorDetectionStateChangeEvent(ArmSensorDetected);
}
if (IsArmed == true && IsStay == false)
{
foreach (ISensor sensor in sensors)
{
sensor.OnDetectionStateChanged += new Events.SensorDetectionStateChangeEvent(ArmSensorDetected);
}
}
else if (IsArmed == true && IsStay == true)
{
foreach (ISensor sensor in sensors)
{
sensor.OnDetectionStateChanged += new Events.SensorDetectionStateChangeEvent(ArmStaySensorDetected);
}
}
else if (IsArmed == false && IsStay == false)
{
alarm.StopAlarm();
}
foreach (ISensor sensor in sensors)
{
sensor.OnDetectionStateChanged += new Events.SensorDetectionStateChangeEvent(SmokeSensorDetected);
}
}
public void Run()
{
// initial delegete bind
DelegateHandling();
//delegate sensor
for (;;)
{
Thread.Sleep(100);
SystemCheck();
if (IsArmedLastSate != IsArmed || IsStayLastSate != IsStay)
{
// when Security Controller change mode, rebind all sensors' delegete.
DelegateHandling();
IsArmedLastSate = IsArmed;
IsStayLastSate = IsStay;
}
}
}
static int Main(string[] args)
{
//...
return 0;
}
}
}
我使用NUnit和最小起訂量繼續處理的單元測試。系統檢查通行證的單元測試。通過NUnit測試框架給出
using HomeSecuritySystem.Alarm;
using HomeSecuritySystem.Sensors;
using Moq;
using System.Collections.Generic;
namespace HomeSecuritySystem
{
using Comms;
using Display;
using NUnit.Framework;
using Power;
[TestFixture]
public class SecurityControllerTest
{
[Test]
public void Test_System_Check()
{
//arrange
Mock<IMotionSensor> mockMotionSensor = new Mock<IMotionSensor>();
mockMotionSensor.SetupGet(t => t.IsLowBattery).Returns(true);
//mock sensors
Mock<List<ISensor>> mockSensors = new Mock<List<ISensor>>();
mockSensors.Object.Add(mockMotionSensor.Object);
foreach (ISensor sensor in mockSensors.Object)
{
if (sensor.IsOn == false)
;
}
Mock<IComms> mockComms = new Mock<IComms>();
mockComms.SetupGet(t => t.IsOn).Returns(true);
Mock<IPowerSupply> mockPowerSupply = new Mock<IPowerSupply>();
mockPowerSupply.SetupGet(t => t.IsOn).Returns(true);
Mock<IAlarm> mockAlarm = new Mock<IAlarm>();
mockAlarm.SetupGet(t => t.IsOn).Returns(true);
Mock<IDisplay> mockDisplay = new Mock<IDisplay>();
SecurityController securityController = new SecurityController(mockSensors.Object, mockComms.Object, mockPowerSupply.Object, mockAlarm.Object, mockDisplay.Object);
//act
Assert.AreEqual(securityController.SystemCheckPass(), true);
}
}
}
錯誤:
Test Name: Test_System_Check
Test FullName: HomeSecuritySystem.SecurityControllerTest.Test_System_Check
Test Source: C:\Users\OEM\Documents\Visual Studio 2015\Projects\HomeSecurityController\HomeSecurityController.UnitTest\SecurityControllerTest.cs : line 17
Test Outcome: Failed
Test Duration: 0:00:00.569
Result StackTrace:
at HomeSecuritySystem.SecurityController.SystemCheckPass() in C:\Users\OEM\Documents\Visual Studio 2015\Projects\HomeSecurityController\HomeSecurityController\SecurityController.cs:line 58
at HomeSecuritySystem.SecurityControllerTest.Test_System_Check() in C:\Users\OEM\Documents\Visual Studio 2015\Projects\HomeSecurityController\HomeSecurityController.UnitTest\SecurityControllerTest.cs:line 42
Result Message: System.NullReferenceException : Object reference not set to an instance of an object.
我只是你使用Visual Studio 4.6 ... –
@PatrickQuirk 「印象深刻」 –