1

I am writing a unit test and in it trying to setup a simple generic list containg mocks of an entity class...

Dim schedules = New List(Of Schedule) From
     {
         Mock.Of(Of Schedule)(Function(s) s.ActiveFrom = "2010-01-01" AndAlso
                                          s.ActiveUntil = New DateTime?("2110-01-01"))
     }


Schedule.ActiveFrom is a Date and Schedule.ActiveUntill is a Nullable(Of Date).

When i run the unit test i get the following error message...

The binary operator AndAlso is not defined for the types 'System.Nullable[System.Boolean] >and System.Boolean


I'm stumped; Where am I going wrong?

ding_jimmy
  • 48
  • 4

2 Answers2

0

The problem is that you actually have two different types. VB can't handle that. So you want to trap the nullable portion and if it is null, return a straight boolean.

One thing you can do is change:

s.ActiveUntil = New DateTime?("2110-01-01")

to

if(s.ActiveUntil is Nothing, FALSE, s.ActiveUntil = New DateTime?("2110-01-01"))

This way, if the field is null, a simple boolean is returned, and if it is not null, you can return the boolean results of the compare.

sloth
  • 99,095
  • 21
  • 171
  • 219
Norm
  • 31
  • 3
0

This isn't of much help to your VB Unit test, but the C# equivalent works just fine:

 var schedules = new List<Schedule>
 {
    Mock.Of<Schedule>(
    s => s.ActiveFrom == new DateTime(2010, 01, 01) 
       && s.ActiveUntil == new Nullable<DateTime>(new DateTime(2110, 01, 01)))
 };

 Assert.IsTrue((schedules.Count == 1) && 
     schedules.Single(_ => (_.ActiveFrom == new DateTime(2010, 01, 01))
     && (_.ActiveUntil == new DateTime(2110, 01, 01))) != null);

It also isn't related to the implicit comparison of DateTime to DateTime? either as careful unpacking of the DateTime? also fails:

 AndAlso If(Not s.ActiveUntil.HasValue, False, 
            s.ActiveUntil.Value = New DateTime("2110-01-01")

I believe the issue may relate to Mock.Of's usage of parsed Expressions during construction of the mock from the predicate provided - possibly there is nuance in VB which wasn't considered.

If so, and assuming you don't want to change your unit tests to C#, you may need to either need to build the Expressions by hand to get the Mock.Of(predicate) goodness to work, or revert to old style creation of your Mock / Fake objects:

  Dim scheduleMock As New Mock(Of Schedule)
  scheduleMock.SetupGet(Function(s) s.ActiveFrom).Returns("2010-01-01")
  scheduleMock.SetupGet(Function(s) s.ActiveUntil).Returns(New DateTime?("2110-01-01"))
  Dim schedules = New List(Of Schedule) From
       {
           scheduleMock.Object
       }

  Assert.IsTrue(schedules.Count = 1)
  Assert.IsTrue(schedules.First.ActiveFrom = "2010-01-01" 
                AndAlso schedules.First.ActiveUntil = "2110-01-01")
Community
  • 1
  • 1
StuartLC
  • 104,537
  • 17
  • 209
  • 285
  • I believe you are correct, and I have gone back to the old style mock creation. The following works: `dim sched = Mock.Of(Of Schedule)() Mock.Get(sched).SetupProperty(Function(s) s.ActiveUntil, New Date?("2110-01-01"))` – ding_jimmy Aug 14 '14 at 13:29