chevron-thin-right chevron-thin-left brand cancel-circle search youtube-icon google-plus-icon linkedin-icon facebook-icon twitter-icon toolbox download check linkedin phone twitter-old google-plus facebook profile-male chat calendar profile-male
0 votes
I have a method that takes username/password and returns a userId based on match in a DB using linq to sql, how would i go about to create tests against this method? Should i refactor the whole metod, if so - how would be the best way? - very new to the linq syntax and testing.

        public long GetUserIdByUsernameAndPassword(string username, string password)
        {
            var db = new DataContext(DataBaseUtil.ConnectionString);

            var query =
                from credentials in db.GetTable<DbAccountCredential>().ToList()
                where credentials.UserName == username && credentials.PassWord == password
                select (new {credentials.AccountId});

            return query.SingleOrDefault().AccountId;
        }
asked by AlexanderViken (1.1k points)

2 Answers

0 votes
Hi Alex,

If you want to test the linq expression you probably want to fake DataContext.GetTable or extract the the data base access to a separate class which seems like a better idea :)
Here's an example:
public class DataAccsess
{
    public List<DbAccountCredential> GetTable()
    {
        var db = new DataContext(DataBaseUtil.ConnectionString);
        return db.GetTable<DbAccountCredential>().ToList();
    }
}

public long GetUserIdByUsernameAndPassword(string username, string password)
{
    DataAccsess dataAccsess = new DataAccsess();
    var table = dataAccsess.GetTable();

    var query =
        from credentials in table
        where credentials.UserName == username && credentials.PassWord == password
        select (new { credentials.AccountId });

    return query.SingleOrDefault().AccountId;
}        

[Test]
public void Test()
{
    var fakeList = new List<DbAccountCredential>();
    
    var fake = Isolate.Fake.Instance<DataAccsess>();
    Isolate.WhenCalled(() => fake.GetTable()).WillReturn(fakeList);
    Isolate.Swap.NextInstance<DataAccsess>().With(fake);

    var foo = new Foo();
    long actual = foo.GetUserIdByUsernameAndPassword("user", "password");
    //...
}



Hope that I guessed right about what you want to test :D
Please let me know if it helps.
answered by ohad (35.4k points)
0 votes
Thank you for the help :D got me into what i think was the best way of doing it... Didn't want the GetTable() to return a List.

public class DataAccsess 
{ 
    public Table<DbAccountCredential> GetTable() 
    { 
        var db = new DataContext(DataBaseUtil.ConnectionString); 
        return db.GetTable<DbAccountCredential>(); 
    } 
}
......
public long GetUserIdByUsernameAndPassword(string username, string password)
{ 
    DataAccsess dataAccsess = new DataAccsess(); 
    var table = dataAccsess.GetTable(); 

    var query = 
        from credentials in table.ToList();
        where credentials.UserName == username && credentials.PassWord == password 
        select (new { credentials.AccountId }); 

    return query.SingleOrDefault().AccountId; 
} 
...........
[Test,Isolated]
public void GetUserIdByUsernameAndPassword_ValidUsernameAndPassword_ReturnsUserIdAsLong()
{
    List<DbAccountCredential> fakeList = GetFakeAccountCredentialsList();
    long validUserIdToReturn = 1;
    string username = "admin";
    string password = "admin";
    var fakeAccess = Isolate.Fake.Instance<DataBaseUtil>();
    var foo = new LoginModel();

    Isolate.WhenCalled(() => fakeAccess.GetAccountCredentialsTable().ToList()).WillReturn(fakeList);
    Isolate.Swap.NextInstance<DataBaseUtil>().With(fakeAccess);
            
    long actual = foo.GetUserIdByUsernameAndPassword(username, password);

    Assert.AreEqual(actual, validUserIdToReturn);
}


"Feels" like the correct way of doing it and it makes the GetTable() method more reusable.
answered by AlexanderViken (1.1k points)
...