PECS (производитель extends
и потребитель super
)
Мнемоника → принцип Get и Put.
Этот принцип гласит, что:
В Java параметры и параметры типового типа не поддерживают наследование следующим образом.
class Super {
void testCoVariance(Object parameter){} // method Consumes the Object
Object testContraVariance(){ return null;} //method Produces the Object
}
class Sub extends Super {
@Override
void testCoVariance(String parameter){} //doesn't support eventhough String is subtype of Object
@Override
String testContraVariance(){ return null;} //compiles successfully i.e. return type is don't care
}
Принцип подстановки Лискова: Массивы являются ковариантными (небезопасными), но Generics не являются, то есть инвариантными (безопасными). Принцип подстановки не работает с параметризованными типами, что означает, что это незаконно писать. Ковариант просто означает, что X
является подтипом Y
, тогда X[]
также будет подтипом Y[]
.
Object name= new String("prem"); //works
List numbers = new ArrayList();//gets compile time error
Integer[] myInts = {1,2,3,4};
Number[] myNumber = myInts;
myNumber[0] = 3.14; //attempt of heap pollution i.e. at runtime gets java.lang.ArrayStoreException: java.lang.Double(we can fool compiler but not run-time)
List list=new ArrayList<>();
list.add("prem");
List
ограниченный (т. е. заголовок к чему-либо) подстановочный знак: Есть 3 разных варианта подстановочных знаков:
?
или ? extends Object
- неограниченный подстановочный знак. Он обозначает семью всех типов. Использовать, когда вы оба получаете и ставите. ? extends T
(семейство всех типов, которые являются подтипами T
) - подстановочный знак с верхней границей. T
является самым верхним классом в иерархии наследования. Используйте подстановочный знак extends
, когда вы получаете только значения из структуры. ? super T
(семейство всех типов, которые являются супертипами T
) - подстановочный знак с нижней границей. T
является самым низким классом в иерархии наследования. Используйте подстановочный символ super
, если вы только поместите значения в структуру. Примечание: подстановочный знак ?
означает ноль или один раз, представляет неизвестный тип. Подстановочный знак может использоваться как тип параметра, никогда не используемый в качестве аргумента типа для вызова общего метода, создания экземпляра универсального класса (т. Е. При использовании подстановочного знака, эта ссылка не используется в другом месте программы, как мы используем T
).
class Shape { void draw() {}}
class Circle extends Shape {void draw() {}}
class Square extends Shape {void draw() {}}
class Rectangle extends Shape {void draw() {}}
public class TestContraVariance {
/*
* Example for an upper bound wildcard (Get values i.e Producer `extends`)
*
* */
public void testCoVariance(List extends Shape> list) {
list.add(new Shape()); // Error: is not applicable for the arguments (Shape) i.e. inheritance is not supporting
list.add(new Circle()); // Error: is not applicable for the arguments (Circle) i.e. inheritance is not supporting
list.add(new Square()); // Error: is not applicable for the arguments (Square) i.e. inheritance is not supporting
list.add(new Rectangle()); // Error: is not applicable for the arguments (Rectangle) i.e. inheritance is not supporting
Shape shape= list.get(0);//compiles so list act as produces only
/*You can't add a Shape,Circle,Square,Rectangle to a List extends Shape>
* You can get an object and know that it will be an Shape
*/
}
/*
* Example for a lower bound wildcard (Put values i.e Consumer`super`)
* */
public void testContraVariance(List super Shape> list) {
list.add(new Shape());//compiles i.e. inheritance is supporting
list.add(new Circle());//compiles i.e. inheritance is supporting
list.add(new Square());//compiles i.e. inheritance is supporting
list.add(new Rectangle());//compiles i.e. inheritance is supporting
Shape shape= list.get(0); // Error: Type mismatch, so list acts only as consumer
Object object= list.get(0); // gets an object, but we don't know what kind of Object it is.
/*You can add a Shape,Circle,Square,Rectangle to a List extends Shape>
* You can't get an Shape(but can get Object) and don't know what kind of Shape it is.
*/
}
}
Потребитель Вашего сервиса не заботится о том, что под Вашим сервисом. Для реального тестирования уровня служб я думаю потребности слоя снизиться до DLLs и базы данных и записи по крайней мере тест CRUD.
Если Вы хотите к модульному тесту, Ваши классы обслуживания WCF удостоверяются, что Вы разрабатываете их со слабой связью в памяти, таким образом, можно дразнить каждую зависимость, поскольку Вы только хотите протестировать логику в самом классе обслуживания.
, Например, в ниже сервиса я вспыхиваю свой репозиторий доступа к данным с помощью "Внедрение зависимости Бедного Человека".
Public Class ProductService
Implements IProductService
Private mRepository As IProductRepository
Public Sub New()
mRepository = New ProductRepository()
End Sub
Public Sub New(ByVal repository As IProductRepository)
mRepository = repository
End Sub
Public Function GetProducts() As System.Collections.Generic.List(Of Product) Implements IProductService.GetProducts
Return mRepository.GetProducts()
End Function
End Class
На клиенте можно дразнить сам сервис WCF с помощью интерфейса контракта на обслуживание.
<TestMethod()> _
Public Sub ShouldPopulateProductsListOnViewLoadWhenPostBackIsFalse()
mMockery = New MockRepository()
mView = DirectCast(mMockery.Stub(Of IProductView)(), IProductView)
mProductService = DirectCast(mMockery.DynamicMock(Of IProductService)(), IProductService)
mPresenter = New ProductPresenter(mView, mProductService)
Dim ProductList As New List(Of Product)()
ProductList.Add(New Product)
Using mMockery.Record()
SetupResult.For(mView.PageIsPostBack).Return(False).Repeat.Once()
Expect.Call(mProductService.GetProducts()).Return(ProductList).Repeat.Once()
End Using
Using mMockery.Playback()
mPresenter.OnViewLoad()
End Using
'Verify that we hit the service dependency during the method when postback is false
Assert.AreEqual(1, mView.Products.Count)
mMockery.VerifyAll()
End Sub
Это зависит от того, что делает тонкий сервис WCF. Если это действительно тонко и там нет никакого интересного кода, не беспокойте поблочное тестирование это. Не бойтесь к не модульный тест что-то, если нет никакого реального кода там. Если тест не может быть по крайней мере одним уровнем, более простым затем код под тестом, не беспокоиться. Если код будет немым, то тест также будет немым. Вы не хотите иметь более немой код для поддержания.
, Если у Вас могут быть тесты, которые переходят полностью к дб, затем большому! Это еще лучше. Это не "истинный модульный тест?" Не проблема вообще.