could not run this unit test with mock - vb.net

I tried to make an unit test for this method which is pretty simple only add an object into the data base and if it works well returns true
Public Shared Function CrearCliente(ByVal cliente As Cliente) As Boolean
Try
db.Cliente.Add(cliente)
db.SaveChanges()
Return True
Catch ex As Exception
Throw New Exception("ocurrio un error guardando al cliente")
End Try
End Function
Now here's my test
<TestMethod()>
Public Sub CrearClienteTest()
Dim mock = New Moq.Mock(Of Cliente)
Dim actual As Boolean
mock.Setup(Function(x) x.Nombre).Returns("blah")
'mock.Setup(Function(x) x.Apellido()
actual = Class1.CrearCliente(mock.Object)
Assert.AreEqual(True, actual)
End Sub
Pretty easy my question is why when Debugged the test throws this error
Invalid setup on a non-virtual (overridable in VB) member: x => x.Nombre
What could be wrong? do i need another configuration?

As the error states, Moq requires that the member you mock be Overridable.

Related

Using <DataTestMethod>, <DataRow....> with vb.net . Only one <DataRow> gets executed

I'm trying to set up an automated unit test using MSTest. I have single tests working, and am now trying to set up parameterised tests using < DataTestMethod> and < DataRow(...)>. I'm following the examples here
When I debug the test sequence below, the ParseTestData( ) is only called once, with the first <DataRow ..> parameter. It is not called a second time.
Can anyone see where I'm going wrong?
(Note: I found some articles indicating DataTestMethod is obsolete, and TestMethod works just the same. I tried and got identical results)
[edit] - from #Mark Seemann 's suggestion, I've simplified this from the original post. Same problem.
Imports Microsoft.VisualStudio.TestTools.UnitTesting
Namespace TestDecoder.Tests
<TestClass>
Public Class DecoderTests
Private DecoderInstance
<DataTestMethod>
<DataRow(New Byte() {&H41})>
<DataRow(New Byte() {&H42})>
Public Sub ParseTestData(Frame() As Byte)
Dim result As Boolean
DecoderInstance = New Decoder()
result = DecoderInstance.parse(Frame(0))
Assert.IsTrue(result, "Failed the dummy test")
End Sub
End Class
End Namespace
I'm not sure if this will provide any more insight, but here is the Decoder code (Edited for Brevity).
Imports Microsoft.VisualBasic
Public Class Decoder
Function parse(rxchar As Byte) As Boolean
Return rxchar = &H41
End Function
End Class

Call instance method inline after New statement

How can i convert this code to VB.net
public void SetBooks(IEnumerable<Book> books)
{
if (books == null)
throw new ArgumentNullException("books");
new System.Xml.Linq.XDocument(books).Save(_filename);
}
in http://converter.telerik.com/ it says:
Public Sub SetBooks(books As IEnumerable(Of Book))
If books Is Nothing Then
Throw New ArgumentNullException("books")
End If
New System.Xml.Linq.XDocument(books).Save(_filename)
End Sub
But visual studio says "Syntax error." because of "New"
What is the keyword for this situation, i searched on Google but no result.
Actually, you can do it in one line with the Call keyword
Call (New System.Xml.Linq.XDocument(books)).Save(_filename)
You cannot initialize an object and use it in one statement in VB.NET (as opposed to C#). You need two:
Dim doc = New System.Xml.Linq.XDocument(books)
doc.Save(_filename)
In C# the constructor returns the instance of the created object, in VB.NET not.

Context issue in IHttpHandler

Sorry, this can be a basic question for advanced VB.NET programmers but I am a beginner in VB.NET so I need your advice.
I have a web application and the login is required for some specific pages. To check if the user is logged in, the old programmer used this technique:
Dim sv As New WL.SessionVariables(Me.Context)
If Not (sv.IsLoggedIn) Then
Response.Redirect(WL.SiteMap.GetLoginURL())
End If
Well, I have to use this Logged In checking in a handler done by me and I tried this:
Public Class CustomHandler
Implements System.Web.IHttpHandler, IReadOnlySessionState
Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest
Dim sv As New WL.SessionVariables(context)
If Not (sv.IsLoggedIn) Then
context.Response.Write("No access unless you're the CEO!!!" & sv.IsLoggedIn)
ElseIf sv.IsLoggedIn Then
DownloadFile(context)
Else
End If
End Sub
//other code
End Class
Well, the "is logged in" checking is always false (even after I login) and I think it's an issue with the context. So all the other pages works fine with logging checking but this handler have this specific issue.
Can you guys give a helping hand?
UPDATE:
The logged in is done trough this method:
Public Sub SetCreditialCookie(ByVal accountID As Integer)
Me.AccountID = accountID
m_context.Session.Item("loggedInAccount") = accountID
m_context.Response.Cookies.Add(New System.Web.HttpCookie("account_id", CStr(m_context.Session.Item("account_id"))))
m_context.Response.Cookies("account_id").Expires = DateTime.Now.AddDays(5)
End Sub
and to check it it's logged in, this method is called:
Public Function IsLoggedIn() As Boolean
If Not m_context.Session.Item("loggedInAccount") Is Nothing And Me.AccountID = m_context.Session.Item("loggedInAccount") Then
Return True
Else
Return False
End If
End Function
UPDATE 2:
- debugging the code shown that there were multiple kind of logins and I was checking the wrong one with the session.
Due to the use of IReadOnlySessionState, is it possible that the SessionVariables class attempts in some way to modify the Session, which in turn causes an error (possibly handled and not visible to you).
If this is the case it could mean that the IsLoggedIn property is not correctly initialised, or does not function as expected?
Do you have access to the code for the class. If so, try debugging it to see what is happening.

FakeItEasy VB.NET issues with parameters

Ok, I am trying to teach myself testing using a mock framework and I work in VB.NET, I am new to lambda expressions and all my previous applications were written in version 2005 or earlier. I now have 2010.
So I have tried Rhino.Mocks but found it difficult to get my head around it mostly because of the older syntax. Since, no-one seems to be bloggin in VB.NET these days, I have been looking at C# examples and trying to figure out what is going on.
So I have a situation where I pass an interface to the constructor of a class and hold a refrence to that interface. When an method is called on the object and event is raise that should be handled by the class that implements the inteface.
I was having trouble, so I tried to create a simple version in C# and repeat the steps in vb.net.
So my interface:
public interface IBroadcastClient
{
void MessageReceivedHandler(string msg);
}
The class that raises the events:
public class Broadcaster
{
public Broadcaster(IBroadcastClient c)
{
_client= c;
this.SendMessage += new MessageReceived(_client.MessageReceivedHandler);
}
private IBroadcastClient _client;
public event MessageReceived SendMessage;
public void SendMessageNow()
{
string _Message;
if (SendMessage != null)
{
_Message = #"Yay!";
SendMessage(_Message);
}
}
}
The test:
[TestMethod]
public void TestSendMessageWithIgnoreParameter()
{
//string msg = #"Yay!";
var client = A.Fake<IBroadcastClient>();
Broadcaster b = new Broadcaster(client);
b.SendMessageNow();
A.CallTo(() => client.MessageReceivedHandler(A<string>.Ignored)).MustHaveHappened();
}
This passes, no problems so far.
Now to try the same this in vb.net;
The same interface and broadcaster class, just in vb.net rather than C# with initially hte following unit test.
<TestMethod()>
Public Sub TestMethod1()
Dim client = A.Fake(Of IBroadcastClient)()
Dim b As New Broadcaster(client)
b.SendMessageNow()
NextCall.To(client).MustHaveHappened()
client.MessageReceivedHandler(A(Of String).Ignored)
End Sub
This fails with the following error message;
" Assertion failed for the following call:
TestFakeItEasyVB.IBroadcastClient.MessageReceivedHandler(msg: )
Expected to find it at least once but found it #0 times among the calls:
1: TestFakeItEasyVB.IBroadcastClient.MessageReceivedHandler(msg: "Yay!")"
Funnily enough writing it this way;
<TestMethod()>
Public Sub TestMethod3()
Dim client = A.Fake(Of IBroadcastClient)()
Dim b As New Broadcaster(client)
b.SendMessageNow()
A.CallTo(Sub() client.MessageReceivedHandler(A(Of String).Ignored)).MustNotHaveHappened()
End Sub
Will also fail with the same error message, however, this version of the test passes.
<TestMethod()>
Public Sub TestMethod2()
Dim client = A.Fake(Of IBroadcastClient)()
Dim b As New Broadcaster(client)
b.SendMessageNow()
NextCall.To(client).MustHaveHappened()
client.MessageReceivedHandler("Yay!")
End Sub
This variation also passes in C#, my quandry is what am I doing wrong to get the test to ignore the argument passed to the faked event handler?
The NextCall-syntax is there for legacy reasons, it's better to use the expression syntax:
A.CallTo(Sub() client.MessageReceivedHandler(A(Of String).Ignored)).MustNotHaveHappened()
In your tests above all others has MustHaveHappened, but this specific one has MustNotHaveHappened, I guess that's why your test is failing. I've compiled your code and run it and once it's changed to MustHaveHappened the test passes.
Currently you can not use argument constraints in the VB-specific "NextCall"-syntax. However you can use the method "WhenArgumentsMatch" to rewrite your first test like this:
<TestMethod()>
Public Sub TestMethod1()
Dim client = A.Fake(Of IBroadcastClient)()
Dim b As New Broadcaster(client)
b.SendMessageNow()
NextCall.To(client).WhenArgumentsMatch(Function(a) a.Get(Of String)(0) = "Yay!").MustHaveHappened()
client.MessageReceivedHandler(Nothing)
End Sub
Or you could use the extension "WithAnyArguments" to ignore all arguments:
<TestMethod()>
Public Sub TestMethod1()
Dim client = A.Fake(Of IBroadcastClient)()
Dim b As New Broadcaster(client)
b.SendMessageNow()
NextCall.To(client).WithAnyArguments().MustHaveHappened()
client.MessageReceivedHandler(Nothing)
End Sub

How get correct Exception from ADO.NET about foreign key violation

I would like to get correct Exception from ADO.NET about foreign key violation. Is there a way to do that?
I am using try to catch ADO.Exception and check it message text for 'foreign'. So, if there is 'foreign' text in exception text, it is a violation and I can alert.
Is it the right way to do or any other method?
try{
base.Delete();
IList<Issue> issues = Issue.LoadForX(this);
foreach (Issue issue in issues)
{
issue.X= null;
issue.SaveAndCheckChanged(user);
}
}
catch(NHibernate.ADOException exception)
{...
You can do this by creating a class that implements the ISQLExceptionConverter interface.
Here is an example implementation for SQL Server:
Public Class MsSqlExceptionConverter
Implements ISQLExceptionConverter
Private Enum SqlServerError As Integer
ConstraintViolation = 2627
ConstraintConflict = 547
End Enum
Public Function Convert(ByVal adoExceptionContextInfo As Global.NHibernate.Exceptions.AdoExceptionContextInfo) As System.Exception _
Implements Global.NHibernate.Exceptions.ISQLExceptionConverter.Convert
Dim sqle As SqlException = TryCast(ADOExceptionHelper.ExtractDbException(adoExceptionContextInfo.SqlException), SqlException)
If sqle IsNot Nothing Then
Select Case sqle.Number
Case SqlServerError.ConstraintConflict
Return New ConstraintConflictException(InternalExceptionMessages.ConstraintConflictOccured, adoExceptionContextInfo.SqlException)
Case SqlServerError.ConstraintViolation
Return New ConstraintViolationException(InternalExceptionMessages.ConstraintViolationOccured, adoExceptionContextInfo.SqlException)
End Select
End If
Return SQLStateConverter.HandledNonSpecificException(adoExceptionContextInfo.SqlException, adoExceptionContextInfo.Message, adoExceptionContextInfo.Sql)
End Function
End Class
To make use of this, define it in your NHibernate config file as follows:
<property name="sql_exception_converter">YourProduct.Infrastructure.NHibernate.ExceptionConverters.MsSqlExceptionConverter, YourProduct.Infrastructure</property>
Overall, this feature is (more or less) undocumented, but you can find some information on Fabio Maulo's blog.