title: C# mock test - Moq List can't be 'foreach', told 'NullReferenceException'
body: <p><strong>Enviroment: NUnit 2.6.4; NUnit TestAdapter 2.0.0; Moq 4.2.1; VisualStdio 4.6;</strong></p>
  
  <p><strong>Brief:</strong>
  I implemet a HomeSecuritySystem in which have vendor's sensor, alarm, PowerSuply, display's interface. I want to test its implement. I want to test 'SystemCheckPass' subroutine.</p>
  
  <p>I mock a List of ISensor and construct 'SecurityController', then I run 'SystemCheckPass' subroutine. When it execute in to the 'SystemCheckPass' subroutine, the 'foreach' doesn't run properly, it says 'NullReferenceException'.</p>
  
  <p>It is all good in the test function for the 'foreach' loop on MockList of ISensors. After simply pass the ref to the 'SecurityController', the 'foreach' 'loop' of 'list' can't find the 'ref' of its elements. I am very confused about it. </p>
  
  <p>Could somebody tell me why?</p>
  
  <p><strong>implementation of the security controller.</strong></p>
  
  <pre><code>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&lt;ISensor&gt; sensors;
          public IComms comms;
          public IPowerSupply powerSupply;
          public IAlarm alarm;
          public IDisplay display;
  
          public SecurityController(ICollection&lt;ISensor&gt; 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()
          {
              // &lt;---- 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 ----&gt;
              return systemCheckPass;
          }
  
          public override void SystemCheck()
          {
              // &lt;---- begin system check
              bool systemCheckPass = true;
              List&lt;int&gt; lowBatterySensorIDList = new List&lt;int&gt;();
  
              // 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 ----&gt;
  
              // &lt;---- report begin
              if (systemCheckPass)
              {
                  display.ShowSystemReady();
              }
              else
              {
                  display.ShowSystemNotReady();
              }
  
              if (lowBatterySensorExist)
              {
                  display.ShowSensorLowBattery(lowBatterySensorIDList);
              }
              if (BatteryOfPowSupplyIsLow)
              {
                  display.ShowPowerSupplyLowBattery();
              }
              // report end ---&gt;
          }
  
          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 &amp;&amp; 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 &amp;&amp; IsStay == false)
              {
                  foreach (ISensor sensor in sensors)
                  {
                      sensor.OnDetectionStateChanged += new Events.SensorDetectionStateChangeEvent(ArmSensorDetected);
                  }
              }
              else if (IsArmed == true &amp;&amp; IsStay == true)
              {
                  foreach (ISensor sensor in sensors)
                  {
                      sensor.OnDetectionStateChanged += new Events.SensorDetectionStateChangeEvent(ArmStaySensorDetected);
                  }
              }
              else if (IsArmed == false &amp;&amp; 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;
          }
      }
  }
  </code></pre>
  
  <p><strong>I use NUnit and Moq to proceed a UnitTest. Unit test of the System Check Pass.</strong></p>
  
  <pre><code>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&lt;IMotionSensor&gt; mockMotionSensor = new Mock&lt;IMotionSensor&gt;();
              mockMotionSensor.SetupGet(t =&gt; t.IsLowBattery).Returns(true);
  
              //mock sensors
              Mock&lt;List&lt;ISensor&gt;&gt; mockSensors = new Mock&lt;List&lt;ISensor&gt;&gt;();
              mockSensors.Object.Add(mockMotionSensor.Object);
  
              foreach (ISensor sensor in mockSensors.Object)
              {
                  if (sensor.IsOn == false)
                      ;
              }
  
              Mock&lt;IComms&gt; mockComms = new Mock&lt;IComms&gt;();
              mockComms.SetupGet(t =&gt; t.IsOn).Returns(true);
              Mock&lt;IPowerSupply&gt; mockPowerSupply = new Mock&lt;IPowerSupply&gt;();
              mockPowerSupply.SetupGet(t =&gt; t.IsOn).Returns(true);
              Mock&lt;IAlarm&gt; mockAlarm = new Mock&lt;IAlarm&gt;();
              mockAlarm.SetupGet(t =&gt; t.IsOn).Returns(true);
              Mock&lt;IDisplay&gt; mockDisplay = new Mock&lt;IDisplay&gt;();
              SecurityController securityController = new SecurityController(mockSensors.Object, mockComms.Object, mockPowerSupply.Object, mockAlarm.Object, mockDisplay.Object);
  
              //act
              Assert.AreEqual(securityController.SystemCheckPass(), true);
          }
      }
  }
  </code></pre>
  
  <p><strong>Error given by NUnit Test Framework:</strong></p>
  
  <pre><code>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.
  </code></pre>