1

I have a trouble 'the Project Manager' give me a project (almost a final product) to test it.

It's a big project in Silverlight, that I coded the end part.

Here there a lot of problems (to Testing), the database connections(the data layer, services, session storage, etc) there in closed dll's from another project(which I don't have access to the source code), these dlls contains a Collection class like:

public class SomeCollection
{
    public static SomeCollection GetCollectionByName(string name);
}

And there another utility class used to control threads, review errors, the finished/completion of data load, and probably more:

public static class BasicUtilities
{
    public static T ExecuteAndFinish(this T baseclass, Action<T> loaded);

    public static T ExecuteAndFinish(this T baseclass, Action<T> loaded, Action<bool> errors);
}

Then in the ViewModel where I need to load the data and populate it in a some kind of control, etc. A common call is like:

public class SomeViewModel : ViewModelBase
{
    ...
    SomeCollection.GetCollectionByName("AIdentifier").ExecuteAndFinish
    (collectionLoaded) =>
    {
            //do something with the collection, populate a control, grid, listbox, etc
    });
    ...
}

Then I want to Test SomeViewModel, "clarifying" that I'm newbie in Tests. There a two frameworks that I could use, moq (for mocking special Models, UtilyClass, DataProviders , etc) or Ninject (for DI, I don't know much about it).

An approach could be overload the constructor of SomeViewModel for the test to pass a mocked object to a new Virtual property of type SomeCollection that replace the common call used:

public class SomeViewModel : ViewModelBase
{
    ...

    SomeCollectionProperty.GetCollectionByName("AIdentifier").ExecuteAndFinish
    (collectionLoaded) =>
    {
            //do something with the collection, populate a control, grid, listbox, etc
    });

    ...
    public virtual SomeClass SomeCollectionProperty { get; set; }
    ...
}

That don't will work because I can't mock the static method GetCollectionByName of the class SomeCollection, even worse I can't modify that dll's.

With DI seems that will happen something like this, and will not work, I don't know.

Seems that I need obligatorily modify the code of everywhere, but I can't modify the datalayer.dll(grouping it).

What I've to do? Many thanks.

4

2 回答 2

1

Please don't consider the following a non-answer. You asked about "testing" not "unit testing."

Unit testing means testing each individual piece in isolation. Its main benefit is it pinpoints the problem code quickly. This is useful in crappy languages like JavaScript that don't provide many compiler checks and rely on testing to identify the most elementary bugs. A unit test is almost like a compiler telling you "error at line 42." It also great during development--you test your piece of code before using it in the application (and feel confident you won't have to debug it later). Its drawbacks are that it is fragile (code changes mean lots of test changes), requires a lot of mucking about with mocks, and that you have to design the code carefully (which is too late for you).

Integration testing tests pieces together. Its main benefit is the testing is more thorough (classes can work great in isolation, but break when actually used together because their design is wrong), and it is much less fragile. The drawback is you may need to set up a whole external environment with databases, servers, etc. for the tests to run. But, again, this lets you test that everything does work together.

I think at this point you should write integration tests. This does not mean sacrificing code coverage. If all the lines of code in your app do real work, then it's perfectly possible to set up integration tests that hit each of them.

Integration tests can exist at various levels (the highest being functional testing--testing the app at its interface to the world), so you can break up the code into chunks and test each chunk rather than the app as a whole.

于 2012-12-17T08:15:54.963 回答
0

Short answer:
Use Typemock Isolator - It can mock everything (private static methods in closed dlls, like GetCollectionByName included), but it's a commercial product.

Less short answer:
Building an application according to the SOLID principles, practicing TDD and continues refactoring and code improvement, would have solved your problem (or rather you wouldn't have this problem in the first place).
Your units of logic would have been separated, and Moq would allow easy testing for all your interface dependent classes.
Throwing some tests at a near finished (well, shipped) product is hardly ideal, but you can still add some value by adding as many (good) tests as possible.
Typemock Isolator uses the .Net profiler by injecting code at runtime, replacing the real logic by whatever behavior you choose. This allows for testing of privates, statics, sealed classes, and more.

Full Disclosure: I used to work for Typemock, and now use Moq for most projects (well, because it's free).

于 2012-12-17T07:59:49.003 回答